Package not found. Please check the package name and try again.
rfreeimage 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +1 -0
- data/Rakefile +34 -0
- data/ext/rfreeimage/extconf.rb +35 -0
- data/ext/rfreeimage/rfi_main.c +389 -0
- data/lib/rfreeimage/image.rb +26 -0
- data/lib/rfreeimage/version.rb +3 -0
- data/lib/rfreeimage.rb +3 -0
- data/rfreeimage.gemspec +32 -0
- data/vendor/FreeImage/Makefile +34 -0
- data/vendor/FreeImage/Makefile.cygwin +74 -0
- data/vendor/FreeImage/Makefile.fip +84 -0
- data/vendor/FreeImage/Makefile.gnu +83 -0
- data/vendor/FreeImage/Makefile.iphone +96 -0
- data/vendor/FreeImage/Makefile.mingw +136 -0
- data/vendor/FreeImage/Makefile.osx +115 -0
- data/vendor/FreeImage/Makefile.solaris +66 -0
- data/vendor/FreeImage/Makefile.srcs +6 -0
- data/vendor/FreeImage/README.iphone +19 -0
- data/vendor/FreeImage/README.linux +50 -0
- data/vendor/FreeImage/README.minGW +236 -0
- data/vendor/FreeImage/README.osx +44 -0
- data/vendor/FreeImage/README.solaris +67 -0
- data/vendor/FreeImage/Source/CacheFile.h +92 -0
- data/vendor/FreeImage/Source/DeprecationManager/Deprecated.cpp +36 -0
- data/vendor/FreeImage/Source/DeprecationManager/DeprecationMgr.cpp +103 -0
- data/vendor/FreeImage/Source/DeprecationManager/DeprecationMgr.h +83 -0
- data/vendor/FreeImage/Source/FreeImage/BitmapAccess.cpp +1573 -0
- data/vendor/FreeImage/Source/FreeImage/CacheFile.cpp +271 -0
- data/vendor/FreeImage/Source/FreeImage/ColorLookup.cpp +785 -0
- data/vendor/FreeImage/Source/FreeImage/Conversion.cpp +551 -0
- data/vendor/FreeImage/Source/FreeImage/Conversion16_555.cpp +209 -0
- data/vendor/FreeImage/Source/FreeImage/Conversion16_565.cpp +204 -0
- data/vendor/FreeImage/Source/FreeImage/Conversion24.cpp +252 -0
- data/vendor/FreeImage/Source/FreeImage/Conversion32.cpp +345 -0
- data/vendor/FreeImage/Source/FreeImage/Conversion4.cpp +246 -0
- data/vendor/FreeImage/Source/FreeImage/Conversion8.cpp +305 -0
- data/vendor/FreeImage/Source/FreeImage/ConversionFloat.cpp +194 -0
- data/vendor/FreeImage/Source/FreeImage/ConversionRGB16.cpp +144 -0
- data/vendor/FreeImage/Source/FreeImage/ConversionRGBA16.cpp +147 -0
- data/vendor/FreeImage/Source/FreeImage/ConversionRGBAF.cpp +250 -0
- data/vendor/FreeImage/Source/FreeImage/ConversionRGBF.cpp +243 -0
- data/vendor/FreeImage/Source/FreeImage/ConversionType.cpp +699 -0
- data/vendor/FreeImage/Source/FreeImage/ConversionUINT16.cpp +134 -0
- data/vendor/FreeImage/Source/FreeImage/FreeImage.cpp +226 -0
- data/vendor/FreeImage/Source/FreeImage/FreeImageC.c +22 -0
- data/vendor/FreeImage/Source/FreeImage/FreeImageIO.cpp +175 -0
- data/vendor/FreeImage/Source/FreeImage/GetType.cpp +92 -0
- data/vendor/FreeImage/Source/FreeImage/Halftoning.cpp +474 -0
- data/vendor/FreeImage/Source/FreeImage/J2KHelper.cpp +591 -0
- data/vendor/FreeImage/Source/FreeImage/J2KHelper.h +36 -0
- data/vendor/FreeImage/Source/FreeImage/LFPQuantizer.cpp +208 -0
- data/vendor/FreeImage/Source/FreeImage/MNGHelper.cpp +1320 -0
- data/vendor/FreeImage/Source/FreeImage/MemoryIO.cpp +237 -0
- data/vendor/FreeImage/Source/FreeImage/MultiPage.cpp +974 -0
- data/vendor/FreeImage/Source/FreeImage/NNQuantizer.cpp +507 -0
- data/vendor/FreeImage/Source/FreeImage/PSDParser.cpp +1057 -0
- data/vendor/FreeImage/Source/FreeImage/PSDParser.h +271 -0
- data/vendor/FreeImage/Source/FreeImage/PixelAccess.cpp +197 -0
- data/vendor/FreeImage/Source/FreeImage/Plugin.cpp +822 -0
- data/vendor/FreeImage/Source/FreeImage/PluginBMP.cpp +1494 -0
- data/vendor/FreeImage/Source/FreeImage/PluginCUT.cpp +240 -0
- data/vendor/FreeImage/Source/FreeImage/PluginDDS.cpp +655 -0
- data/vendor/FreeImage/Source/FreeImage/PluginEXR.cpp +773 -0
- data/vendor/FreeImage/Source/FreeImage/PluginG3.cpp +433 -0
- data/vendor/FreeImage/Source/FreeImage/PluginGIF.cpp +1407 -0
- data/vendor/FreeImage/Source/FreeImage/PluginHDR.cpp +722 -0
- data/vendor/FreeImage/Source/FreeImage/PluginICO.cpp +824 -0
- data/vendor/FreeImage/Source/FreeImage/PluginIFF.cpp +459 -0
- data/vendor/FreeImage/Source/FreeImage/PluginJ2K.cpp +328 -0
- data/vendor/FreeImage/Source/FreeImage/PluginJNG.cpp +162 -0
- data/vendor/FreeImage/Source/FreeImage/PluginJP2.cpp +328 -0
- data/vendor/FreeImage/Source/FreeImage/PluginJPEG.cpp +1706 -0
- data/vendor/FreeImage/Source/FreeImage/PluginJXR.cpp +1475 -0
- data/vendor/FreeImage/Source/FreeImage/PluginKOALA.cpp +243 -0
- data/vendor/FreeImage/Source/FreeImage/PluginMNG.cpp +153 -0
- data/vendor/FreeImage/Source/FreeImage/PluginPCD.cpp +251 -0
- data/vendor/FreeImage/Source/FreeImage/PluginPCX.cpp +659 -0
- data/vendor/FreeImage/Source/FreeImage/PluginPFM.cpp +409 -0
- data/vendor/FreeImage/Source/FreeImage/PluginPICT.cpp +1343 -0
- data/vendor/FreeImage/Source/FreeImage/PluginPNG.cpp +1115 -0
- data/vendor/FreeImage/Source/FreeImage/PluginPNM.cpp +838 -0
- data/vendor/FreeImage/Source/FreeImage/PluginPSD.cpp +131 -0
- data/vendor/FreeImage/Source/FreeImage/PluginRAS.cpp +512 -0
- data/vendor/FreeImage/Source/FreeImage/PluginRAW.cpp +793 -0
- data/vendor/FreeImage/Source/FreeImage/PluginSGI.cpp +425 -0
- data/vendor/FreeImage/Source/FreeImage/PluginTARGA.cpp +1591 -0
- data/vendor/FreeImage/Source/FreeImage/PluginTIFF.cpp +2631 -0
- data/vendor/FreeImage/Source/FreeImage/PluginWBMP.cpp +372 -0
- data/vendor/FreeImage/Source/FreeImage/PluginWebP.cpp +698 -0
- data/vendor/FreeImage/Source/FreeImage/PluginXBM.cpp +399 -0
- data/vendor/FreeImage/Source/FreeImage/PluginXPM.cpp +487 -0
- data/vendor/FreeImage/Source/FreeImage/TIFFLogLuv.cpp +65 -0
- data/vendor/FreeImage/Source/FreeImage/ToneMapping.cpp +75 -0
- data/vendor/FreeImage/Source/FreeImage/WuQuantizer.cpp +559 -0
- data/vendor/FreeImage/Source/FreeImage/ZLibInterface.cpp +223 -0
- data/vendor/FreeImage/Source/FreeImage/tmoColorConvert.cpp +479 -0
- data/vendor/FreeImage/Source/FreeImage/tmoDrago03.cpp +295 -0
- data/vendor/FreeImage/Source/FreeImage/tmoFattal02.cpp +689 -0
- data/vendor/FreeImage/Source/FreeImage/tmoReinhard05.cpp +260 -0
- data/vendor/FreeImage/Source/FreeImage.h +1153 -0
- data/vendor/FreeImage/Source/FreeImageIO.h +63 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/BSplineRotate.cpp +730 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Background.cpp +895 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Channels.cpp +488 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/ClassicRotate.cpp +917 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Colors.cpp +967 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/CopyPaste.cpp +861 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Display.cpp +230 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Filters.h +287 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Flip.cpp +166 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/JPEGTransform.cpp +623 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/MultigridPoissonSolver.cpp +505 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Rescale.cpp +192 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Resize.cpp +2116 -0
- data/vendor/FreeImage/Source/FreeImageToolkit/Resize.h +196 -0
- data/vendor/FreeImage/Source/LibJPEG/ansi2knr.c +739 -0
- data/vendor/FreeImage/Source/LibJPEG/cderror.h +134 -0
- data/vendor/FreeImage/Source/LibJPEG/cdjpeg.c +181 -0
- data/vendor/FreeImage/Source/LibJPEG/cdjpeg.h +187 -0
- data/vendor/FreeImage/Source/LibJPEG/cjpeg.c +664 -0
- data/vendor/FreeImage/Source/LibJPEG/ckconfig.c +402 -0
- data/vendor/FreeImage/Source/LibJPEG/djpeg.c +617 -0
- data/vendor/FreeImage/Source/LibJPEG/example.c +433 -0
- data/vendor/FreeImage/Source/LibJPEG/jaricom.c +153 -0
- data/vendor/FreeImage/Source/LibJPEG/jcapimin.c +288 -0
- data/vendor/FreeImage/Source/LibJPEG/jcapistd.c +162 -0
- data/vendor/FreeImage/Source/LibJPEG/jcarith.c +944 -0
- data/vendor/FreeImage/Source/LibJPEG/jccoefct.c +454 -0
- data/vendor/FreeImage/Source/LibJPEG/jccolor.c +604 -0
- data/vendor/FreeImage/Source/LibJPEG/jcdctmgr.c +477 -0
- data/vendor/FreeImage/Source/LibJPEG/jchuff.c +1573 -0
- data/vendor/FreeImage/Source/LibJPEG/jcinit.c +84 -0
- data/vendor/FreeImage/Source/LibJPEG/jcmainct.c +297 -0
- data/vendor/FreeImage/Source/LibJPEG/jcmarker.c +719 -0
- data/vendor/FreeImage/Source/LibJPEG/jcmaster.c +856 -0
- data/vendor/FreeImage/Source/LibJPEG/jcomapi.c +106 -0
- data/vendor/FreeImage/Source/LibJPEG/jconfig.h +161 -0
- data/vendor/FreeImage/Source/LibJPEG/jcparam.c +675 -0
- data/vendor/FreeImage/Source/LibJPEG/jcprepct.c +358 -0
- data/vendor/FreeImage/Source/LibJPEG/jcsample.c +545 -0
- data/vendor/FreeImage/Source/LibJPEG/jctrans.c +385 -0
- data/vendor/FreeImage/Source/LibJPEG/jdapimin.c +399 -0
- data/vendor/FreeImage/Source/LibJPEG/jdapistd.c +276 -0
- data/vendor/FreeImage/Source/LibJPEG/jdarith.c +796 -0
- data/vendor/FreeImage/Source/LibJPEG/jdatadst.c +270 -0
- data/vendor/FreeImage/Source/LibJPEG/jdatasrc.c +275 -0
- data/vendor/FreeImage/Source/LibJPEG/jdcoefct.c +741 -0
- data/vendor/FreeImage/Source/LibJPEG/jdcolor.c +748 -0
- data/vendor/FreeImage/Source/LibJPEG/jdct.h +393 -0
- data/vendor/FreeImage/Source/LibJPEG/jddctmgr.c +384 -0
- data/vendor/FreeImage/Source/LibJPEG/jdhuff.c +1554 -0
- data/vendor/FreeImage/Source/LibJPEG/jdinput.c +662 -0
- data/vendor/FreeImage/Source/LibJPEG/jdmainct.c +513 -0
- data/vendor/FreeImage/Source/LibJPEG/jdmarker.c +1511 -0
- data/vendor/FreeImage/Source/LibJPEG/jdmaster.c +543 -0
- data/vendor/FreeImage/Source/LibJPEG/jdmerge.c +401 -0
- data/vendor/FreeImage/Source/LibJPEG/jdpostct.c +290 -0
- data/vendor/FreeImage/Source/LibJPEG/jdsample.c +361 -0
- data/vendor/FreeImage/Source/LibJPEG/jdtrans.c +140 -0
- data/vendor/FreeImage/Source/LibJPEG/jerror.c +253 -0
- data/vendor/FreeImage/Source/LibJPEG/jerror.h +304 -0
- data/vendor/FreeImage/Source/LibJPEG/jfdctflt.c +174 -0
- data/vendor/FreeImage/Source/LibJPEG/jfdctfst.c +230 -0
- data/vendor/FreeImage/Source/LibJPEG/jfdctint.c +4406 -0
- data/vendor/FreeImage/Source/LibJPEG/jidctflt.c +235 -0
- data/vendor/FreeImage/Source/LibJPEG/jidctfst.c +368 -0
- data/vendor/FreeImage/Source/LibJPEG/jidctint.c +5179 -0
- data/vendor/FreeImage/Source/LibJPEG/jinclude.h +91 -0
- data/vendor/FreeImage/Source/LibJPEG/jmemansi.c +167 -0
- data/vendor/FreeImage/Source/LibJPEG/jmemdos.c +638 -0
- data/vendor/FreeImage/Source/LibJPEG/jmemmac.c +289 -0
- data/vendor/FreeImage/Source/LibJPEG/jmemmgr.c +1119 -0
- data/vendor/FreeImage/Source/LibJPEG/jmemname.c +276 -0
- data/vendor/FreeImage/Source/LibJPEG/jmemnobs.c +109 -0
- data/vendor/FreeImage/Source/LibJPEG/jmemsys.h +198 -0
- data/vendor/FreeImage/Source/LibJPEG/jmorecfg.h +442 -0
- data/vendor/FreeImage/Source/LibJPEG/jpegint.h +426 -0
- data/vendor/FreeImage/Source/LibJPEG/jpeglib.h +1180 -0
- data/vendor/FreeImage/Source/LibJPEG/jpegtran.c +577 -0
- data/vendor/FreeImage/Source/LibJPEG/jquant1.c +857 -0
- data/vendor/FreeImage/Source/LibJPEG/jquant2.c +1311 -0
- data/vendor/FreeImage/Source/LibJPEG/jutils.c +227 -0
- data/vendor/FreeImage/Source/LibJPEG/jversion.h +14 -0
- data/vendor/FreeImage/Source/LibJPEG/rdbmp.c +480 -0
- data/vendor/FreeImage/Source/LibJPEG/rdcolmap.c +253 -0
- data/vendor/FreeImage/Source/LibJPEG/rdgif.c +38 -0
- data/vendor/FreeImage/Source/LibJPEG/rdjpgcom.c +515 -0
- data/vendor/FreeImage/Source/LibJPEG/rdppm.c +459 -0
- data/vendor/FreeImage/Source/LibJPEG/rdrle.c +387 -0
- data/vendor/FreeImage/Source/LibJPEG/rdswitch.c +365 -0
- data/vendor/FreeImage/Source/LibJPEG/rdtarga.c +500 -0
- data/vendor/FreeImage/Source/LibJPEG/transupp.c +1763 -0
- data/vendor/FreeImage/Source/LibJPEG/transupp.h +219 -0
- data/vendor/FreeImage/Source/LibJPEG/wrbmp.c +442 -0
- data/vendor/FreeImage/Source/LibJPEG/wrgif.c +399 -0
- data/vendor/FreeImage/Source/LibJPEG/wrjpgcom.c +583 -0
- data/vendor/FreeImage/Source/LibJPEG/wrppm.c +269 -0
- data/vendor/FreeImage/Source/LibJPEG/wrrle.c +305 -0
- data/vendor/FreeImage/Source/LibJPEG/wrtarga.c +253 -0
- data/vendor/FreeImage/Source/LibJXR/common/include/guiddef.h +230 -0
- data/vendor/FreeImage/Source/LibJXR/common/include/wmsal.h +757 -0
- data/vendor/FreeImage/Source/LibJXR/common/include/wmspecstring.h +342 -0
- data/vendor/FreeImage/Source/LibJXR/common/include/wmspecstrings_adt.h +71 -0
- data/vendor/FreeImage/Source/LibJXR/common/include/wmspecstrings_strict.h +1096 -0
- data/vendor/FreeImage/Source/LibJXR/common/include/wmspecstrings_undef.h +406 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/JXRTranscode.c +987 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/decode.c +200 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/decode.h +143 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/postprocess.c +288 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/segdec.c +1205 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/strInvTransform.c +1888 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/strPredQuantDec.c +539 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/strdec.c +3628 -0
- data/vendor/FreeImage/Source/LibJXR/image/decode/strdec_x86.c +1640 -0
- data/vendor/FreeImage/Source/LibJXR/image/encode/encode.c +144 -0
- data/vendor/FreeImage/Source/LibJXR/image/encode/encode.h +113 -0
- data/vendor/FreeImage/Source/LibJXR/image/encode/segenc.c +1186 -0
- data/vendor/FreeImage/Source/LibJXR/image/encode/strFwdTransform.c +1111 -0
- data/vendor/FreeImage/Source/LibJXR/image/encode/strPredQuantEnc.c +511 -0
- data/vendor/FreeImage/Source/LibJXR/image/encode/strenc.c +2370 -0
- data/vendor/FreeImage/Source/LibJXR/image/encode/strenc_x86.c +409 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/adapthuff.c +511 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/ansi.h +61 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/common.h +131 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/image.c +183 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/perfTimer.h +115 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/perfTimerANSI.c +274 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/strPredQuant.c +306 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/strTransform.c +85 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/strTransform.h +50 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/strcodec.c +1251 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/strcodec.h +681 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/windowsmediaphoto.h +515 -0
- data/vendor/FreeImage/Source/LibJXR/image/sys/xplatform_image.h +84 -0
- data/vendor/FreeImage/Source/LibJXR/image/x86/x86.h +58 -0
- data/vendor/FreeImage/Source/LibJXR/jxrgluelib/JXRGlue.c +930 -0
- data/vendor/FreeImage/Source/LibJXR/jxrgluelib/JXRGlue.h +636 -0
- data/vendor/FreeImage/Source/LibJXR/jxrgluelib/JXRGlueJxr.c +2246 -0
- data/vendor/FreeImage/Source/LibJXR/jxrgluelib/JXRGluePFC.c +2338 -0
- data/vendor/FreeImage/Source/LibJXR/jxrgluelib/JXRMeta.c +905 -0
- data/vendor/FreeImage/Source/LibJXR/jxrgluelib/JXRMeta.h +258 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/bio.c +188 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/bio.h +128 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/cidx_manager.c +239 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/cidx_manager.h +68 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/cio.c +644 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/cio.h +393 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/dwt.c +919 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/dwt.h +116 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/event.c +141 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/event.h +97 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/function_list.c +114 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/function_list.h +126 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/image.c +235 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/image.h +63 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/indexbox_manager.h +148 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/invert.c +289 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/invert.h +59 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/j2k.c +10238 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/j2k.h +838 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/jp2.c +2776 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/jp2.h +490 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/mct.c +319 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/mct.h +149 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/mqc.c +604 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/mqc.h +201 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/openjpeg.c +955 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/openjpeg.h +1475 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_clock.c +59 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_clock.h +54 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_codec.h +160 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_config.h +9 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_config_private.h +16 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_includes.h +175 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_intmath.h +172 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_inttypes.h +43 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_malloc.h +180 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/opj_stdint.h +47 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/phix_manager.c +191 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/pi.c +1870 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/pi.h +182 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/ppix_manager.c +194 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/raw.c +89 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/raw.h +100 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/t1.c +1751 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/t1.h +157 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/t1_generate_luts.c +276 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/t1_luts.h +143 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/t2.c +1334 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/t2.h +127 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/tcd.c +2123 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/tcd.h +348 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/tgt.c +331 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/tgt.h +140 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/thix_manager.c +134 -0
- data/vendor/FreeImage/Source/LibOpenJPEG/tpix_manager.c +185 -0
- data/vendor/FreeImage/Source/LibPNG/example.c +1061 -0
- data/vendor/FreeImage/Source/LibPNG/png.c +4493 -0
- data/vendor/FreeImage/Source/LibPNG/png.h +3282 -0
- data/vendor/FreeImage/Source/LibPNG/pngconf.h +644 -0
- data/vendor/FreeImage/Source/LibPNG/pngdebug.h +154 -0
- data/vendor/FreeImage/Source/LibPNG/pngerror.c +963 -0
- data/vendor/FreeImage/Source/LibPNG/pngget.c +1213 -0
- data/vendor/FreeImage/Source/LibPNG/pnginfo.h +260 -0
- data/vendor/FreeImage/Source/LibPNG/pnglibconf.h +218 -0
- data/vendor/FreeImage/Source/LibPNG/pngmem.c +281 -0
- data/vendor/FreeImage/Source/LibPNG/pngpread.c +1168 -0
- data/vendor/FreeImage/Source/LibPNG/pngpriv.h +1944 -0
- data/vendor/FreeImage/Source/LibPNG/pngread.c +4121 -0
- data/vendor/FreeImage/Source/LibPNG/pngrio.c +120 -0
- data/vendor/FreeImage/Source/LibPNG/pngrtran.c +4994 -0
- data/vendor/FreeImage/Source/LibPNG/pngrutil.c +4474 -0
- data/vendor/FreeImage/Source/LibPNG/pngset.c +1611 -0
- data/vendor/FreeImage/Source/LibPNG/pngstruct.h +489 -0
- data/vendor/FreeImage/Source/LibPNG/pngtest.c +2011 -0
- data/vendor/FreeImage/Source/LibPNG/pngtrans.c +849 -0
- data/vendor/FreeImage/Source/LibPNG/pngwio.c +168 -0
- data/vendor/FreeImage/Source/LibPNG/pngwrite.c +2455 -0
- data/vendor/FreeImage/Source/LibPNG/pngwtran.c +574 -0
- data/vendor/FreeImage/Source/LibPNG/pngwutil.c +3029 -0
- data/vendor/FreeImage/Source/LibRawLite/dcraw/dcraw.c +15462 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/aahd_demosaic.cpp +706 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/dcb_demosaicing.c +710 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/dcraw_common.cpp +13593 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/dcraw_fileio.cpp +240 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/defines.h +167 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/demosaic_packs.cpp +99 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/dht_demosaic.cpp +873 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/libraw_internal_funcs.h +282 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/libraw_x3f.cpp +1919 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/var_defines.h +216 -0
- data/vendor/FreeImage/Source/LibRawLite/internal/wf_filtering.cpp +1950 -0
- data/vendor/FreeImage/Source/LibRawLite/libraw/libraw.h +338 -0
- data/vendor/FreeImage/Source/LibRawLite/libraw/libraw_alloc.h +99 -0
- data/vendor/FreeImage/Source/LibRawLite/libraw/libraw_const.h +233 -0
- data/vendor/FreeImage/Source/LibRawLite/libraw/libraw_datastream.h +238 -0
- data/vendor/FreeImage/Source/LibRawLite/libraw/libraw_internal.h +225 -0
- data/vendor/FreeImage/Source/LibRawLite/libraw/libraw_types.h +442 -0
- data/vendor/FreeImage/Source/LibRawLite/libraw/libraw_version.h +62 -0
- data/vendor/FreeImage/Source/LibRawLite/src/libraw_c_api.cpp +230 -0
- data/vendor/FreeImage/Source/LibRawLite/src/libraw_cxx.cpp +4533 -0
- data/vendor/FreeImage/Source/LibRawLite/src/libraw_datastream.cpp +703 -0
- data/vendor/FreeImage/Source/LibTIFF4/mkg3states.c +451 -0
- data/vendor/FreeImage/Source/LibTIFF4/mkspans.c +82 -0
- data/vendor/FreeImage/Source/LibTIFF4/t4.h +292 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_aux.c +358 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_close.c +140 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_codec.c +166 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_color.c +287 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_compress.c +304 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_config.h +97 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_config.vc.h +74 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_config.wince.h +71 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_dir.c +1700 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_dir.h +308 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_dirinfo.c +959 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_dirread.c +5640 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_dirwrite.c +2910 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_dumpmode.c +143 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_error.c +80 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_extension.c +118 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_fax3.c +1595 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_fax3.h +538 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_fax3sm.c +1260 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_flush.c +118 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_getimage.c +2890 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_jbig.c +213 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_jpeg.c +2354 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_jpeg_12.c +65 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_luv.c +1683 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_lzma.c +495 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_lzw.c +1169 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_next.c +181 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_ojpeg.c +2501 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_open.c +725 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_packbits.c +300 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_pixarlog.c +1442 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_predict.c +764 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_predict.h +77 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_print.c +716 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_read.c +1086 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_strip.c +383 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_swab.c +310 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_thunder.c +207 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_tile.c +299 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_unix.c +325 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_version.c +40 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_vms.c +603 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_warning.c +81 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_win32.c +443 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_wince.c +293 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_write.c +771 -0
- data/vendor/FreeImage/Source/LibTIFF4/tif_zip.c +472 -0
- data/vendor/FreeImage/Source/LibTIFF4/tiff.h +681 -0
- data/vendor/FreeImage/Source/LibTIFF4/tiffconf.h +170 -0
- data/vendor/FreeImage/Source/LibTIFF4/tiffconf.vc.h +160 -0
- data/vendor/FreeImage/Source/LibTIFF4/tiffconf.wince.h +121 -0
- data/vendor/FreeImage/Source/LibTIFF4/tiffio.h +557 -0
- data/vendor/FreeImage/Source/LibTIFF4/tiffiop.h +367 -0
- data/vendor/FreeImage/Source/LibTIFF4/tiffvers.h +9 -0
- data/vendor/FreeImage/Source/LibTIFF4/uvcode.h +180 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/alphai.h +55 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.alpha.c +167 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.buffer.c +249 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.frame.c +827 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.idec.c +857 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.io.c +640 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.quant.c +110 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.tree.c +525 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.vp8.c +663 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.vp8l.c +1584 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/dec.webp.c +834 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/decode_vp8.h +185 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/vp8i.h +353 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/vp8li.h +136 -0
- data/vendor/FreeImage/Source/LibWebP/src/dec/webpi.h +120 -0
- data/vendor/FreeImage/Source/LibWebP/src/demux/demux.demux.c +957 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.alpha_processing.c +377 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.alpha_processing_mips_dsp_r2.c +139 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.alpha_processing_sse2.c +296 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.argb.c +68 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.argb_mips_dsp_r2.c +108 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.argb_sse2.c +62 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.cost.c +412 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.cost_mips32.c +154 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.cost_mips_dsp_r2.c +107 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.cost_sse2.c +121 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.cpu.c +138 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.dec.c +760 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.dec_clip_tables.c +366 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.dec_mips32.c +585 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.dec_mips_dsp_r2.c +992 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.dec_neon.c +1489 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.dec_sse2.c +1284 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.enc.c +788 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.enc_avx2.c +24 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.enc_mips32.c +670 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.enc_mips_dsp_r2.c +1510 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.enc_neon.c +932 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.enc_sse2.c +940 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.filters.c +240 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c +404 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.filters_sse2.c +349 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.h +434 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.lossless.c +1838 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.lossless_mips32.c +416 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.lossless_mips_dsp_r2.c +921 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.lossless_neon.c +357 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.lossless_sse2.c +535 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.rescaler.c +115 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.rescaler_mips32.c +192 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.rescaler_mips_dsp_r2.c +210 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.upsampling.c +252 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.upsampling_mips_dsp_r2.c +280 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.upsampling_neon.c +267 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.upsampling_sse2.c +214 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.yuv.c +166 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.yuv_mips32.c +100 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.yuv_mips_dsp_r2.c +131 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/dsp.yuv_sse2.c +322 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/lossless.h +313 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/mips_macro.h +200 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/neon.h +82 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/yuv.h +321 -0
- data/vendor/FreeImage/Source/LibWebP/src/dsp/yuv_tables_sse2.h +536 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/backward_references.h +202 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/cost.h +69 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.alpha.c +440 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.analysis.c +501 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.backward_references.c +1076 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.config.c +163 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.cost.c +355 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.filter.c +296 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.frame.c +850 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.histogram.c +897 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.iterator.c +456 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.near_lossless.c +160 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.picture.c +290 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.picture_csp.c +1100 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.picture_psnr.c +150 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.picture_rescale.c +285 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.picture_tools.c +206 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.quant.c +1191 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.syntax.c +383 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.token.c +285 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.tree.c +504 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.vp8l.c +1437 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/enc.webpenc.c +379 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/histogram.h +114 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/vp8enci.h +551 -0
- data/vendor/FreeImage/Source/LibWebP/src/enc/vp8li.h +78 -0
- data/vendor/FreeImage/Source/LibWebP/src/mux/mux.anim_encode.c +1241 -0
- data/vendor/FreeImage/Source/LibWebP/src/mux/mux.muxedit.c +696 -0
- data/vendor/FreeImage/Source/LibWebP/src/mux/mux.muxinternal.c +551 -0
- data/vendor/FreeImage/Source/LibWebP/src/mux/mux.muxread.c +544 -0
- data/vendor/FreeImage/Source/LibWebP/src/mux/muxi.h +232 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/bit_reader.h +168 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/bit_reader_inl.h +172 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/bit_writer.h +120 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/color_cache.h +74 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/endian_inl.h +100 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/filters.h +32 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/huffman.h +67 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/huffman_encode.h +60 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/quant_levels.h +36 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/quant_levels_dec.h +35 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/random.h +63 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/rescaler.h +78 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/thread.h +93 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.bit_reader.c +208 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.bit_writer.c +308 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.color_cache.c +49 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.filters.c +76 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.h +121 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.huffman.c +205 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.huffman_encode.c +417 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.quant_levels.c +140 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.quant_levels_dec.c +279 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.random.c +43 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.rescaler.c +82 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.thread.c +309 -0
- data/vendor/FreeImage/Source/LibWebP/src/utils/utils.utils.c +211 -0
- data/vendor/FreeImage/Source/LibWebP/src/webp/decode.h +493 -0
- data/vendor/FreeImage/Source/LibWebP/src/webp/demux.h +224 -0
- data/vendor/FreeImage/Source/LibWebP/src/webp/encode.h +515 -0
- data/vendor/FreeImage/Source/LibWebP/src/webp/format_constants.h +88 -0
- data/vendor/FreeImage/Source/LibWebP/src/webp/mux.h +507 -0
- data/vendor/FreeImage/Source/LibWebP/src/webp/mux_types.h +97 -0
- data/vendor/FreeImage/Source/LibWebP/src/webp/types.h +52 -0
- data/vendor/FreeImage/Source/MapIntrospector.h +212 -0
- data/vendor/FreeImage/Source/Metadata/Exif.cpp +1253 -0
- data/vendor/FreeImage/Source/Metadata/FIRational.cpp +176 -0
- data/vendor/FreeImage/Source/Metadata/FIRational.h +108 -0
- data/vendor/FreeImage/Source/Metadata/FreeImageTag.cpp +353 -0
- data/vendor/FreeImage/Source/Metadata/FreeImageTag.h +500 -0
- data/vendor/FreeImage/Source/Metadata/IPTC.cpp +342 -0
- data/vendor/FreeImage/Source/Metadata/TagConversion.cpp +1094 -0
- data/vendor/FreeImage/Source/Metadata/TagLib.cpp +1618 -0
- data/vendor/FreeImage/Source/Metadata/XTIFF.cpp +766 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/eLut.cpp +114 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/eLut.h +71 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/half.cpp +310 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/half.h +757 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/halfExport.h +27 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/halfFunction.h +179 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/halfLimits.h +102 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/toFloat.cpp +164 -0
- data/vendor/FreeImage/Source/OpenEXR/Half/toFloat.h +16391 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/Iex.h +60 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexBaseExc.cpp +156 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexBaseExc.h +264 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexErrnoExc.h +208 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexExport.h +51 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexForward.h +229 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexMacros.h +170 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexMathExc.h +57 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexNamespace.h +112 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexThrowErrnoExc.cpp +873 -0
- data/vendor/FreeImage/Source/OpenEXR/Iex/IexThrowErrnoExc.h +97 -0
- data/vendor/FreeImage/Source/OpenEXR/IexMath/IexMathFloatExc.cpp +113 -0
- data/vendor/FreeImage/Source/OpenEXR/IexMath/IexMathFloatExc.h +146 -0
- data/vendor/FreeImage/Source/OpenEXR/IexMath/IexMathFpu.cpp +530 -0
- data/vendor/FreeImage/Source/OpenEXR/IexMath/IexMathFpu.h +91 -0
- data/vendor/FreeImage/Source/OpenEXR/IexMath/IexMathIeeeExc.h +62 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmBaseConfig.h +61 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfAcesFile.cpp +633 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfAcesFile.h +324 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfArray.h +285 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfAttribute.cpp +158 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfAttribute.h +407 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfAutoArray.h +95 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfB44Compressor.cpp +1072 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfB44Compressor.h +118 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfBoxAttribute.cpp +111 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfBoxAttribute.h +87 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCRgbaFile.cpp +1438 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCRgbaFile.h +555 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfChannelList.cpp +322 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfChannelList.h +436 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfChannelListAttribute.cpp +150 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfChannelListAttribute.h +74 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCheckedArithmetic.h +163 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfChromaticities.cpp +151 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfChromaticities.h +131 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.cpp +87 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.h +73 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.cpp +591 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.h +142 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCompression.h +84 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCompressionAttribute.cpp +78 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCompressionAttribute.h +64 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCompressor.cpp +226 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfCompressor.h +265 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfConvert.cpp +143 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfConvert.h +107 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepCompositing.cpp +110 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepCompositing.h +132 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.cpp +230 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.h +339 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepImageState.h +96 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.cpp +78 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.h +68 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp +2025 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.h +276 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.cpp +149 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.h +181 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.cpp +1552 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.h +244 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.cpp +107 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.h +168 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.cpp +1979 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.h +437 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.cpp +273 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.h +362 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.cpp +2055 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.h +475 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.cpp +250 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.h +394 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDoubleAttribute.cpp +57 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDoubleAttribute.h +59 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDwaCompressor.cpp +3424 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDwaCompressor.h +210 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfDwaCompressorSimd.h +2145 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfEnvmap.cpp +335 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfEnvmap.h +336 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.cpp +76 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfEnvmapAttribute.h +68 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfExport.h +46 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFastHuf.cpp +768 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFastHuf.h +148 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFloatAttribute.cpp +57 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFloatAttribute.h +58 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.cpp +84 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.h +76 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfForward.h +127 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFrameBuffer.cpp +228 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFrameBuffer.h +386 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFramesPerSecond.cpp +76 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfFramesPerSecond.h +94 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfGenericInputFile.cpp +76 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfGenericInputFile.h +58 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfGenericOutputFile.cpp +112 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfGenericOutputFile.h +62 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfHeader.cpp +1283 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfHeader.h +699 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfHuf.cpp +1114 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfHuf.h +82 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfIO.cpp +110 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfIO.h +255 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfInputFile.cpp +895 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfInputFile.h +240 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfInputPart.cpp +114 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfInputPart.h +84 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfInputPartData.cpp +51 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfInputPartData.h +69 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfInputStreamMutex.h +68 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfInt64.h +56 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfIntAttribute.cpp +57 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfIntAttribute.h +58 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfKeyCode.cpp +217 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfKeyCode.h +167 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.cpp +99 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.h +73 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfLineOrder.h +69 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.cpp +78 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfLineOrderAttribute.h +72 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfLut.cpp +178 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfLut.h +188 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMatrixAttribute.cpp +263 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMatrixAttribute.h +83 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMisc.cpp +1872 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMisc.h +466 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMultiPartInputFile.cpp +783 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMultiPartInputFile.h +128 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.cpp +519 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.h +118 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMultiView.cpp +435 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfMultiView.h +187 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfName.h +150 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfNamespace.h +115 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.cpp +126 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOpaqueAttribute.h +110 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOptimizedPixelReading.h +646 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOutputFile.cpp +1378 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOutputFile.h +263 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOutputPart.cpp +105 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOutputPart.h +77 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOutputPartData.cpp +52 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOutputPartData.h +62 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfOutputStreamMutex.h +70 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPartHelper.h +262 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPartType.cpp +63 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPartType.h +62 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPixelType.h +67 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPizCompressor.cpp +667 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPizCompressor.h +117 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPreviewImage.cpp +104 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPreviewImage.h +135 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.cpp +103 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.h +70 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPxr24Compressor.cpp +553 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfPxr24Compressor.h +109 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRational.cpp +127 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRational.h +98 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRationalAttribute.cpp +74 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRationalAttribute.h +69 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRgba.h +109 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRgbaFile.cpp +1405 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRgbaFile.h +346 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRgbaYca.cpp +497 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRgbaYca.h +259 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRle.cpp +157 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRle.h +63 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRleCompressor.cpp +220 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfRleCompressor.h +80 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfScanLineInputFile.cpp +1702 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfScanLineInputFile.h +210 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfSimd.h +59 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfStandardAttributes.cpp +125 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfStandardAttributes.h +382 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfStdIO.cpp +242 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfStdIO.h +160 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfStringAttribute.cpp +80 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfStringAttribute.h +71 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.cpp +100 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfStringVectorAttribute.h +74 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfSystemSpecific.cpp +129 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfSystemSpecific.h +172 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTestFile.cpp +216 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTestFile.h +97 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfThreading.cpp +62 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfThreading.h +95 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTileDescription.h +107 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.cpp +86 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.h +72 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTileOffsets.cpp +552 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTileOffsets.h +125 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledInputFile.cpp +1533 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledInputFile.h +401 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledInputPart.cpp +208 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledInputPart.h +100 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledMisc.cpp +389 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledMisc.h +106 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledOutputFile.cpp +1841 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledOutputFile.h +495 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledOutputPart.cpp +228 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledOutputPart.h +105 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.cpp +1163 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTiledRgbaFile.h +482 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTimeCode.cpp +431 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTimeCode.h +242 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.cpp +79 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.h +74 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfVecAttribute.cpp +217 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfVecAttribute.h +100 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfVersion.cpp +60 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfVersion.h +136 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfWav.cpp +391 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfWav.h +78 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfXdr.h +927 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfZip.cpp +196 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfZip.h +78 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfZipCompressor.cpp +127 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/ImfZipCompressor.h +89 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/b44ExpLogTable.cpp +136 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/b44ExpLogTable.h +16396 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/dwaLookups.cpp +573 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmImf/dwaLookups.h +98334 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThread.cpp +80 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThread.h +143 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadExport.h +46 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadForward.h +52 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadMutex.cpp +59 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadMutex.h +160 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadMutexPosix.cpp +85 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadMutexWin32.cpp +79 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadNamespace.h +114 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadPool.cpp +483 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadPool.h +160 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadPosix.cpp +98 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadSemaphore.cpp +60 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadSemaphore.h +112 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosix.cpp +106 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadSemaphorePosixCompat.cpp +155 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadSemaphoreWin32.cpp +153 -0
- data/vendor/FreeImage/Source/OpenEXR/IlmThread/IlmThreadWin32.cpp +100 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathBox.cpp +37 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathBox.h +849 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathBoxAlgo.h +1016 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathColor.h +736 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathColorAlgo.cpp +178 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathColorAlgo.h +257 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathEuler.h +926 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathExc.h +73 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathExport.h +46 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathForward.h +72 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathFrame.h +192 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathFrustum.h +741 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathFrustumTest.h +417 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathFun.cpp +181 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathFun.h +269 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathGL.h +166 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathGLU.h +54 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathHalfLimits.h +68 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathInt64.h +62 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathInterval.h +226 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathLimits.h +268 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathLine.h +185 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathLineAlgo.h +288 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathMath.h +208 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathMatrix.h +3441 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathMatrixAlgo.cpp +1252 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathMatrixAlgo.h +1425 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathNamespace.h +115 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathPlane.h +257 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathPlatform.h +112 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathQuat.h +964 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathRandom.cpp +194 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathRandom.h +401 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathRoots.h +219 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathShear.cpp +54 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathShear.h +656 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathSphere.h +177 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathVec.cpp +583 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathVec.h +2227 -0
- data/vendor/FreeImage/Source/OpenEXR/Imath/ImathVecAlgo.h +147 -0
- data/vendor/FreeImage/Source/OpenEXR/OpenEXRConfig.h +72 -0
- data/vendor/FreeImage/Source/Plugin.h +144 -0
- data/vendor/FreeImage/Source/Quantizers.h +354 -0
- data/vendor/FreeImage/Source/ToneMapping.h +44 -0
- data/vendor/FreeImage/Source/Utilities.h +516 -0
- data/vendor/FreeImage/Source/ZLib/adler32.c +179 -0
- data/vendor/FreeImage/Source/ZLib/compress.c +80 -0
- data/vendor/FreeImage/Source/ZLib/crc32.c +425 -0
- data/vendor/FreeImage/Source/ZLib/crc32.h +441 -0
- data/vendor/FreeImage/Source/ZLib/deflate.c +1967 -0
- data/vendor/FreeImage/Source/ZLib/deflate.h +346 -0
- data/vendor/FreeImage/Source/ZLib/gzclose.c +25 -0
- data/vendor/FreeImage/Source/ZLib/gzguts.h +209 -0
- data/vendor/FreeImage/Source/ZLib/gzlib.c +634 -0
- data/vendor/FreeImage/Source/ZLib/gzread.c +594 -0
- data/vendor/FreeImage/Source/ZLib/gzwrite.c +577 -0
- data/vendor/FreeImage/Source/ZLib/infback.c +640 -0
- data/vendor/FreeImage/Source/ZLib/inffast.c +340 -0
- data/vendor/FreeImage/Source/ZLib/inffast.h +11 -0
- data/vendor/FreeImage/Source/ZLib/inffixed.h +94 -0
- data/vendor/FreeImage/Source/ZLib/inflate.c +1512 -0
- data/vendor/FreeImage/Source/ZLib/inflate.h +122 -0
- data/vendor/FreeImage/Source/ZLib/inftrees.c +306 -0
- data/vendor/FreeImage/Source/ZLib/inftrees.h +62 -0
- data/vendor/FreeImage/Source/ZLib/trees.c +1226 -0
- data/vendor/FreeImage/Source/ZLib/trees.h +128 -0
- data/vendor/FreeImage/Source/ZLib/uncompr.c +59 -0
- data/vendor/FreeImage/Source/ZLib/zconf.h +511 -0
- data/vendor/FreeImage/Source/ZLib/zlib.h +1768 -0
- data/vendor/FreeImage/Source/ZLib/zutil.c +324 -0
- data/vendor/FreeImage/Source/ZLib/zutil.h +253 -0
- metadata +931 -0
|
@@ -0,0 +1,3424 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2009-2014 DreamWorks Animation LLC.
|
|
4
|
+
//
|
|
5
|
+
// All rights reserved.
|
|
6
|
+
//
|
|
7
|
+
// Redistribution and use in source and binary forms, with or without
|
|
8
|
+
// modification, are permitted provided that the following conditions are
|
|
9
|
+
// met:
|
|
10
|
+
// * Redistributions of source code must retain the above copyright
|
|
11
|
+
// notice, this list of conditions and the following disclaimer.
|
|
12
|
+
// * Redistributions in binary form must reproduce the above
|
|
13
|
+
// copyright notice, this list of conditions and the following disclaimer
|
|
14
|
+
// in the documentation and/or other materials provided with the
|
|
15
|
+
// distribution.
|
|
16
|
+
// * Neither the name of DreamWorks Animation nor the names of
|
|
17
|
+
// its contributors may be used to endorse or promote products derived
|
|
18
|
+
// from this software without specific prior written permission.
|
|
19
|
+
//
|
|
20
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
21
|
+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
22
|
+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
23
|
+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
24
|
+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
25
|
+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
26
|
+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
27
|
+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
28
|
+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
29
|
+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
30
|
+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
//
|
|
32
|
+
///////////////////////////////////////////////////////////////////////////
|
|
33
|
+
|
|
34
|
+
//---------------------------------------------------
|
|
35
|
+
//
|
|
36
|
+
// class DwaCompressor -- Store lossy RGB data by quantizing
|
|
37
|
+
// DCT components.
|
|
38
|
+
//
|
|
39
|
+
// First, we try and figure out what compression strategy to take
|
|
40
|
+
// based in channel name. For RGB channels, we want a lossy method
|
|
41
|
+
// described below. But, if we have alpha, we should do something
|
|
42
|
+
// different (and probably using RLE). If we have depth, or velocity,
|
|
43
|
+
// or something else, just fall back to ZIP. The rules for deciding
|
|
44
|
+
// which strategy to use are setup in initializeDefaultChannelRules().
|
|
45
|
+
// When writing a file, the relevant rules needed to decode are written
|
|
46
|
+
// into the start of the data block, making a self-contained file.
|
|
47
|
+
// If initializeDefaultChannelRules() doesn't quite suite your naming
|
|
48
|
+
// conventions, you can adjust the rules without breaking decoder
|
|
49
|
+
// compatability.
|
|
50
|
+
//
|
|
51
|
+
// If we're going to lossy compress R, G, or B channels, it's easier
|
|
52
|
+
// to toss bits in a more perceptual uniform space. One could argue
|
|
53
|
+
// at length as to what constitutes perceptually uniform, expecially
|
|
54
|
+
// when storing either scene/input/focal plane referred and output referred
|
|
55
|
+
// data.
|
|
56
|
+
//
|
|
57
|
+
// We'll compromise. For values <= 1, we use a traditional power function
|
|
58
|
+
// (without any of that straight-line business at the bottom). For values > 1,
|
|
59
|
+
// we want something more like a log function, since power functions blow
|
|
60
|
+
// up. At 1, we want a smooth blend between the functions. So, we use a
|
|
61
|
+
// piecewise function that does just that - see dwaLookups.cpp for
|
|
62
|
+
// a little more detail.
|
|
63
|
+
//
|
|
64
|
+
// Also, if we find that we have R, G, and B channels from the same layer,
|
|
65
|
+
// we can get a bit more compression efficiency by transforming to a Y'CbCr
|
|
66
|
+
// space. We use the 709 transform, but with Cb,Cr = 0 for an input of
|
|
67
|
+
// (0, 0, 0), instead of the traditional Cb,Cr = .5. Shifting the zero point
|
|
68
|
+
// makes no sense with large range data. Transforms are done to from
|
|
69
|
+
// the perceptual space data, not the linear-light space data (R'G'B' ->
|
|
70
|
+
// (Y'CbCr, not RGB -> YCbCr).
|
|
71
|
+
//
|
|
72
|
+
// Next, we forward DCT the data. This is done with a floating
|
|
73
|
+
// point DCT, as we don't really have control over the src range. The
|
|
74
|
+
// resulting values are dropped to half-float precision.
|
|
75
|
+
//
|
|
76
|
+
// Now, we need to quantize. Quantization departs from the usual way
|
|
77
|
+
// of dividing and rounding. Instead, we start with some floating
|
|
78
|
+
// point "base-error" value. From this, we can derive quantization
|
|
79
|
+
// error for each DCT component. Take the standard JPEG quantization
|
|
80
|
+
// tables and normalize them by the smallest value. Then, multiply
|
|
81
|
+
// the normalized quant tables by our base-error value. This gives
|
|
82
|
+
// a range of errors for each DCT component.
|
|
83
|
+
//
|
|
84
|
+
// For each DCT component, we want to find a quantized value that
|
|
85
|
+
// is within +- the per-component error. Pick the quantized value
|
|
86
|
+
// that has the fewest bits set in its' binary representation.
|
|
87
|
+
// Brute-forcing the search would make for extremly inefficient
|
|
88
|
+
// compression. Fortunatly, we can precompute a table to assist
|
|
89
|
+
// with this search.
|
|
90
|
+
//
|
|
91
|
+
// For each 16-bit float value, there are at most 15 other values with
|
|
92
|
+
// fewer bits set. We can precompute these values in a compact form, since
|
|
93
|
+
// many source values have far fewer that 15 possible quantized values.
|
|
94
|
+
// Now, instead of searching the entire range +- the component error,
|
|
95
|
+
// we can just search at most 15 quantization candidates. The search can
|
|
96
|
+
// be accelerated a bit more by sorting the candidates by the
|
|
97
|
+
// number of bits set, in increasing order. Then, the search can stop
|
|
98
|
+
// once a candidate is found w/i the per-component quantization
|
|
99
|
+
// error range.
|
|
100
|
+
//
|
|
101
|
+
// The quantization strategy has the side-benefit that there is no
|
|
102
|
+
// de-quantization step upon decode, so we don't bother recording
|
|
103
|
+
// the quantization table.
|
|
104
|
+
//
|
|
105
|
+
// Ok. So we now have quantized values. Time for entropy coding. We
|
|
106
|
+
// can use either static Huffman or zlib/DEFLATE. The static Huffman
|
|
107
|
+
// is more efficient at compacting data, but can have a greater
|
|
108
|
+
// overhead, especially for smaller tile/strip sizes.
|
|
109
|
+
//
|
|
110
|
+
// There is some additional fun, like ZIP compressing the DC components
|
|
111
|
+
// instead of Huffman/zlib, which helps make things slightly smaller.
|
|
112
|
+
//
|
|
113
|
+
// Compression level is controlled by setting an int/float/double attribute
|
|
114
|
+
// on the header named "dwaCompressionLevel". This is a thinly veiled name for
|
|
115
|
+
// the "base-error" value mentioned above. The "base-error" is just
|
|
116
|
+
// dwaCompressionLevel / 100000. The default value of 45.0 is generally
|
|
117
|
+
// pretty good at generating "visually lossless" values at reasonable
|
|
118
|
+
// data rates. Setting dwaCompressionLevel to 0 should result in no additional
|
|
119
|
+
// quantization at the quantization stage (though there may be
|
|
120
|
+
// quantization in practice at the CSC/DCT steps). But if you really
|
|
121
|
+
// want lossless compression, there are pleanty of other choices
|
|
122
|
+
// of compressors ;)
|
|
123
|
+
//
|
|
124
|
+
// When dealing with FLOAT source buffers, we first quantize the source
|
|
125
|
+
// to HALF and continue down as we would for HALF source.
|
|
126
|
+
//
|
|
127
|
+
//---------------------------------------------------
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
#include "ImfDwaCompressor.h"
|
|
131
|
+
#include "ImfDwaCompressorSimd.h"
|
|
132
|
+
|
|
133
|
+
#include "ImfChannelList.h"
|
|
134
|
+
#include "ImfStandardAttributes.h"
|
|
135
|
+
#include "ImfHeader.h"
|
|
136
|
+
#include "ImfHuf.h"
|
|
137
|
+
#include "ImfInt64.h"
|
|
138
|
+
#include "ImfIntAttribute.h"
|
|
139
|
+
#include "ImfIO.h"
|
|
140
|
+
#include "ImfMisc.h"
|
|
141
|
+
#include "ImfNamespace.h"
|
|
142
|
+
#include "ImfRle.h"
|
|
143
|
+
#include "ImfSimd.h"
|
|
144
|
+
#include "ImfSystemSpecific.h"
|
|
145
|
+
#include "ImfXdr.h"
|
|
146
|
+
#include "ImfZip.h"
|
|
147
|
+
|
|
148
|
+
#include "ImathFun.h"
|
|
149
|
+
#include "ImathBox.h"
|
|
150
|
+
#include "ImathVec.h"
|
|
151
|
+
#include "half.h"
|
|
152
|
+
|
|
153
|
+
#include "dwaLookups.h"
|
|
154
|
+
|
|
155
|
+
#include <vector>
|
|
156
|
+
#include <string>
|
|
157
|
+
#include <cctype>
|
|
158
|
+
#include <cassert>
|
|
159
|
+
#include <algorithm>
|
|
160
|
+
|
|
161
|
+
// Windows specific addition to prevent the indirect import of the redefined min/max macros
|
|
162
|
+
#if defined _WIN32 || defined _WIN64
|
|
163
|
+
#ifdef NOMINMAX
|
|
164
|
+
#undef NOMINMAX
|
|
165
|
+
#endif
|
|
166
|
+
#define NOMINMAX
|
|
167
|
+
#endif
|
|
168
|
+
#include <zlib.h>
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
namespace {
|
|
175
|
+
|
|
176
|
+
//
|
|
177
|
+
// Function pointer to dispatch to an approprate
|
|
178
|
+
// convertFloatToHalf64_* impl, based on runtime cpu checking.
|
|
179
|
+
// Should be initialized in DwaCompressor::initializeFuncs()
|
|
180
|
+
//
|
|
181
|
+
|
|
182
|
+
void (*convertFloatToHalf64)(unsigned short*, float*) =
|
|
183
|
+
convertFloatToHalf64_scalar;
|
|
184
|
+
|
|
185
|
+
//
|
|
186
|
+
// Function pointer for dispatching a fromHalfZigZag_ impl
|
|
187
|
+
//
|
|
188
|
+
|
|
189
|
+
void (*fromHalfZigZag)(unsigned short*, float*) =
|
|
190
|
+
fromHalfZigZag_scalar;
|
|
191
|
+
|
|
192
|
+
//
|
|
193
|
+
// Dispatch the inverse DCT on an 8x8 block, where the last
|
|
194
|
+
// n rows can be all zeros. The n=0 case converts the full block.
|
|
195
|
+
//
|
|
196
|
+
void (*dctInverse8x8_0)(float*) = dctInverse8x8_scalar<0>;
|
|
197
|
+
void (*dctInverse8x8_1)(float*) = dctInverse8x8_scalar<1>;
|
|
198
|
+
void (*dctInverse8x8_2)(float*) = dctInverse8x8_scalar<2>;
|
|
199
|
+
void (*dctInverse8x8_3)(float*) = dctInverse8x8_scalar<3>;
|
|
200
|
+
void (*dctInverse8x8_4)(float*) = dctInverse8x8_scalar<4>;
|
|
201
|
+
void (*dctInverse8x8_5)(float*) = dctInverse8x8_scalar<5>;
|
|
202
|
+
void (*dctInverse8x8_6)(float*) = dctInverse8x8_scalar<6>;
|
|
203
|
+
void (*dctInverse8x8_7)(float*) = dctInverse8x8_scalar<7>;
|
|
204
|
+
|
|
205
|
+
} // namespace
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
struct DwaCompressor::ChannelData
|
|
209
|
+
{
|
|
210
|
+
std::string name;
|
|
211
|
+
CompressorScheme compression;
|
|
212
|
+
int xSampling;
|
|
213
|
+
int ySampling;
|
|
214
|
+
PixelType type;
|
|
215
|
+
bool pLinear;
|
|
216
|
+
|
|
217
|
+
int width;
|
|
218
|
+
int height;
|
|
219
|
+
|
|
220
|
+
//
|
|
221
|
+
// Incoming and outgoing data is scanline interleaved, and it's much
|
|
222
|
+
// easier to operate on contiguous data. Assuming the planare unc
|
|
223
|
+
// buffer is to hold RLE data, we need to rearrange to make bytes
|
|
224
|
+
// adjacent.
|
|
225
|
+
//
|
|
226
|
+
|
|
227
|
+
char *planarUncBuffer;
|
|
228
|
+
char *planarUncBufferEnd;
|
|
229
|
+
|
|
230
|
+
char *planarUncRle[4];
|
|
231
|
+
char *planarUncRleEnd[4];
|
|
232
|
+
|
|
233
|
+
PixelType planarUncType;
|
|
234
|
+
int planarUncSize;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
struct DwaCompressor::CscChannelSet
|
|
239
|
+
{
|
|
240
|
+
int idx[3];
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
struct DwaCompressor::Classifier
|
|
245
|
+
{
|
|
246
|
+
Classifier (std::string suffix,
|
|
247
|
+
CompressorScheme scheme,
|
|
248
|
+
PixelType type,
|
|
249
|
+
int cscIdx,
|
|
250
|
+
bool caseInsensitive):
|
|
251
|
+
_suffix(suffix),
|
|
252
|
+
_scheme(scheme),
|
|
253
|
+
_type(type),
|
|
254
|
+
_cscIdx(cscIdx),
|
|
255
|
+
_caseInsensitive(caseInsensitive)
|
|
256
|
+
{
|
|
257
|
+
if (caseInsensitive)
|
|
258
|
+
transform(_suffix.begin(), _suffix.end(), _suffix.begin(), tolower);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
Classifier (const char *&ptr, int size)
|
|
262
|
+
{
|
|
263
|
+
if (size <= 0)
|
|
264
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
265
|
+
" (truncated rule).");
|
|
266
|
+
|
|
267
|
+
{
|
|
268
|
+
char suffix[Name::SIZE];
|
|
269
|
+
memset (suffix, 0, Name::SIZE);
|
|
270
|
+
Xdr::read<CharPtrIO> (ptr, std::min(size, Name::SIZE-1), suffix);
|
|
271
|
+
_suffix = std::string(suffix);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (size < _suffix.length() + 1 + 2*Xdr::size<char>())
|
|
275
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
276
|
+
" (truncated rule).");
|
|
277
|
+
|
|
278
|
+
char value;
|
|
279
|
+
Xdr::read<CharPtrIO> (ptr, value);
|
|
280
|
+
|
|
281
|
+
_cscIdx = (int)(value >> 4) - 1;
|
|
282
|
+
if (_cscIdx < -1 || _cscIdx >= 3)
|
|
283
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
284
|
+
" (corrupt cscIdx rule).");
|
|
285
|
+
|
|
286
|
+
_scheme = (CompressorScheme)((value >> 2) & 3);
|
|
287
|
+
if (_scheme < 0 || _scheme >= NUM_COMPRESSOR_SCHEMES)
|
|
288
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
289
|
+
" (corrupt scheme rule).");
|
|
290
|
+
|
|
291
|
+
_caseInsensitive = (value & 1 ? true : false);
|
|
292
|
+
|
|
293
|
+
Xdr::read<CharPtrIO> (ptr, value);
|
|
294
|
+
if (value < 0 || value >= NUM_PIXELTYPES)
|
|
295
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
296
|
+
" (corrupt rule).");
|
|
297
|
+
_type = (PixelType)value;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
bool match (const std::string &suffix, const PixelType type) const
|
|
301
|
+
{
|
|
302
|
+
if (_type != type) return false;
|
|
303
|
+
|
|
304
|
+
if (_caseInsensitive)
|
|
305
|
+
{
|
|
306
|
+
std::string tmp(suffix);
|
|
307
|
+
transform(tmp.begin(), tmp.end(), tmp.begin(), tolower);
|
|
308
|
+
return tmp == _suffix;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return suffix == _suffix;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
size_t size () const
|
|
315
|
+
{
|
|
316
|
+
// string length + \0
|
|
317
|
+
size_t sizeBytes = _suffix.length() + 1;
|
|
318
|
+
|
|
319
|
+
// 1 byte for scheme / cscIdx / caseInsensitive, and 1 byte for type
|
|
320
|
+
sizeBytes += 2 * Xdr::size<char>();
|
|
321
|
+
|
|
322
|
+
return sizeBytes;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
void write (char *&ptr) const
|
|
326
|
+
{
|
|
327
|
+
Xdr::write<CharPtrIO> (ptr, _suffix.c_str());
|
|
328
|
+
|
|
329
|
+
// Encode _cscIdx (-1-3) in the upper 4 bits,
|
|
330
|
+
// _scheme (0-2) in the next 2 bits
|
|
331
|
+
// _caseInsen in the bottom bit
|
|
332
|
+
unsigned char value = 0;
|
|
333
|
+
value |= ((unsigned char)(_cscIdx+1) & 15) << 4;
|
|
334
|
+
value |= ((unsigned char)_scheme & 3) << 2;
|
|
335
|
+
value |= (unsigned char)_caseInsensitive & 1;
|
|
336
|
+
|
|
337
|
+
Xdr::write<CharPtrIO> (ptr, value);
|
|
338
|
+
Xdr::write<CharPtrIO> (ptr, (unsigned char)_type);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
std::string _suffix;
|
|
342
|
+
CompressorScheme _scheme;
|
|
343
|
+
PixelType _type;
|
|
344
|
+
int _cscIdx;
|
|
345
|
+
bool _caseInsensitive;
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
//
|
|
350
|
+
// Base class for the LOSSY_DCT decoder classes
|
|
351
|
+
//
|
|
352
|
+
|
|
353
|
+
class DwaCompressor::LossyDctDecoderBase
|
|
354
|
+
{
|
|
355
|
+
public:
|
|
356
|
+
|
|
357
|
+
LossyDctDecoderBase
|
|
358
|
+
(char *packedAc,
|
|
359
|
+
char *packedDc,
|
|
360
|
+
const unsigned short *toLinear,
|
|
361
|
+
int width,
|
|
362
|
+
int height);
|
|
363
|
+
|
|
364
|
+
virtual ~LossyDctDecoderBase ();
|
|
365
|
+
|
|
366
|
+
void execute();
|
|
367
|
+
|
|
368
|
+
//
|
|
369
|
+
// These return number of items, not bytes. Each item
|
|
370
|
+
// is an unsigned short
|
|
371
|
+
//
|
|
372
|
+
|
|
373
|
+
int numAcValuesEncoded() const { return _packedAcCount; }
|
|
374
|
+
int numDcValuesEncoded() const { return _packedDcCount; }
|
|
375
|
+
|
|
376
|
+
protected:
|
|
377
|
+
|
|
378
|
+
//
|
|
379
|
+
// Un-RLE the packed AC components into
|
|
380
|
+
// a half buffer. The half block should
|
|
381
|
+
// be the full 8x8 block (in zig-zag order
|
|
382
|
+
// still), not the first AC component.
|
|
383
|
+
//
|
|
384
|
+
// currAcComp is advanced as bytes are decoded.
|
|
385
|
+
//
|
|
386
|
+
// This returns the index of the last non-zero
|
|
387
|
+
// value in the buffer - with the index into zig zag
|
|
388
|
+
// order data. If we return 0, we have DC only data.
|
|
389
|
+
//
|
|
390
|
+
|
|
391
|
+
int unRleAc (unsigned short *&currAcComp,
|
|
392
|
+
unsigned short *halfZigBlock);
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
//
|
|
396
|
+
// if NATIVE and XDR are really the same values, we can
|
|
397
|
+
// skip some processing and speed things along
|
|
398
|
+
//
|
|
399
|
+
|
|
400
|
+
bool _isNativeXdr;
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
//
|
|
404
|
+
// Counts of how many items have been packed into the
|
|
405
|
+
// AC and DC buffers
|
|
406
|
+
//
|
|
407
|
+
|
|
408
|
+
int _packedAcCount;
|
|
409
|
+
int _packedDcCount;
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
//
|
|
413
|
+
// AC and DC buffers to pack
|
|
414
|
+
//
|
|
415
|
+
|
|
416
|
+
char *_packedAc;
|
|
417
|
+
char *_packedDc;
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
//
|
|
421
|
+
// half -> half LUT to transform from nonlinear to linear
|
|
422
|
+
//
|
|
423
|
+
|
|
424
|
+
const unsigned short *_toLinear;
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
//
|
|
428
|
+
// image dimensions
|
|
429
|
+
//
|
|
430
|
+
|
|
431
|
+
int _width;
|
|
432
|
+
int _height;
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
//
|
|
436
|
+
// Pointers to the start of each scanlines, to be filled on decode
|
|
437
|
+
// Generally, these will be filled by the subclasses.
|
|
438
|
+
//
|
|
439
|
+
|
|
440
|
+
std::vector< std::vector<char *> > _rowPtrs;
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
//
|
|
444
|
+
// The type of each data that _rowPtrs[i] is referring. Layout
|
|
445
|
+
// is in the same order as _rowPtrs[].
|
|
446
|
+
//
|
|
447
|
+
|
|
448
|
+
std::vector<PixelType> _type;
|
|
449
|
+
std::vector<SimdAlignedBuffer64f> _dctData;
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
//
|
|
454
|
+
// Used to decode a single channel of LOSSY_DCT data.
|
|
455
|
+
//
|
|
456
|
+
|
|
457
|
+
class DwaCompressor::LossyDctDecoder: public LossyDctDecoderBase
|
|
458
|
+
{
|
|
459
|
+
public:
|
|
460
|
+
|
|
461
|
+
//
|
|
462
|
+
// toLinear is a half-float LUT to convert the encoded values
|
|
463
|
+
// back to linear light. If you want to skip this step, pass
|
|
464
|
+
// in NULL here.
|
|
465
|
+
//
|
|
466
|
+
|
|
467
|
+
LossyDctDecoder
|
|
468
|
+
(std::vector<char *> &rowPtrs,
|
|
469
|
+
char *packedAc,
|
|
470
|
+
char *packedDc,
|
|
471
|
+
const unsigned short *toLinear,
|
|
472
|
+
int width,
|
|
473
|
+
int height,
|
|
474
|
+
PixelType type)
|
|
475
|
+
:
|
|
476
|
+
LossyDctDecoderBase(packedAc, packedDc, toLinear, width, height)
|
|
477
|
+
{
|
|
478
|
+
_rowPtrs.push_back(rowPtrs);
|
|
479
|
+
_type.push_back(type);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
virtual ~LossyDctDecoder () {}
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
//
|
|
487
|
+
// Used to decode 3 channels of LOSSY_DCT data that
|
|
488
|
+
// are grouped together and color space converted.
|
|
489
|
+
//
|
|
490
|
+
|
|
491
|
+
class DwaCompressor::LossyDctDecoderCsc: public LossyDctDecoderBase
|
|
492
|
+
{
|
|
493
|
+
public:
|
|
494
|
+
|
|
495
|
+
//
|
|
496
|
+
// toLinear is a half-float LUT to convert the encoded values
|
|
497
|
+
// back to linear light. If you want to skip this step, pass
|
|
498
|
+
// in NULL here.
|
|
499
|
+
//
|
|
500
|
+
|
|
501
|
+
LossyDctDecoderCsc
|
|
502
|
+
(std::vector<char *> &rowPtrsR,
|
|
503
|
+
std::vector<char *> &rowPtrsG,
|
|
504
|
+
std::vector<char *> &rowPtrsB,
|
|
505
|
+
char *packedAc,
|
|
506
|
+
char *packedDc,
|
|
507
|
+
const unsigned short *toLinear,
|
|
508
|
+
int width,
|
|
509
|
+
int height,
|
|
510
|
+
PixelType typeR,
|
|
511
|
+
PixelType typeG,
|
|
512
|
+
PixelType typeB)
|
|
513
|
+
:
|
|
514
|
+
LossyDctDecoderBase(packedAc, packedDc, toLinear, width, height)
|
|
515
|
+
{
|
|
516
|
+
_rowPtrs.push_back(rowPtrsR);
|
|
517
|
+
_rowPtrs.push_back(rowPtrsG);
|
|
518
|
+
_rowPtrs.push_back(rowPtrsB);
|
|
519
|
+
_type.push_back(typeR);
|
|
520
|
+
_type.push_back(typeG);
|
|
521
|
+
_type.push_back(typeB);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
virtual ~LossyDctDecoderCsc () {}
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
//
|
|
529
|
+
// Base class for encoding using the lossy DCT scheme
|
|
530
|
+
//
|
|
531
|
+
|
|
532
|
+
class DwaCompressor::LossyDctEncoderBase
|
|
533
|
+
{
|
|
534
|
+
public:
|
|
535
|
+
|
|
536
|
+
LossyDctEncoderBase
|
|
537
|
+
(float quantBaseError,
|
|
538
|
+
char *packedAc,
|
|
539
|
+
char *packedDc,
|
|
540
|
+
const unsigned short *toNonlinear,
|
|
541
|
+
int width,
|
|
542
|
+
int height);
|
|
543
|
+
|
|
544
|
+
virtual ~LossyDctEncoderBase ();
|
|
545
|
+
|
|
546
|
+
void execute ();
|
|
547
|
+
|
|
548
|
+
//
|
|
549
|
+
// These return number of items, not bytes. Each item
|
|
550
|
+
// is an unsigned short
|
|
551
|
+
//
|
|
552
|
+
|
|
553
|
+
int numAcValuesEncoded () const {return _numAcComp;}
|
|
554
|
+
int numDcValuesEncoded () const {return _numDcComp;}
|
|
555
|
+
|
|
556
|
+
protected:
|
|
557
|
+
|
|
558
|
+
void toZigZag (half *dst, half *src);
|
|
559
|
+
int countSetBits (unsigned short src);
|
|
560
|
+
half quantize (half src, float errorTolerance);
|
|
561
|
+
void rleAc (half *block, unsigned short *&acPtr);
|
|
562
|
+
|
|
563
|
+
float _quantBaseError;
|
|
564
|
+
|
|
565
|
+
int _width,
|
|
566
|
+
_height;
|
|
567
|
+
const unsigned short *_toNonlinear;
|
|
568
|
+
|
|
569
|
+
int _numAcComp,
|
|
570
|
+
_numDcComp;
|
|
571
|
+
|
|
572
|
+
std::vector< std::vector<const char *> > _rowPtrs;
|
|
573
|
+
std::vector<PixelType> _type;
|
|
574
|
+
std::vector<SimdAlignedBuffer64f> _dctData;
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
//
|
|
578
|
+
// Pointers to the buffers where AC and DC
|
|
579
|
+
// DCT components should be packed for
|
|
580
|
+
// lossless compression downstream
|
|
581
|
+
//
|
|
582
|
+
|
|
583
|
+
char *_packedAc;
|
|
584
|
+
char *_packedDc;
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
//
|
|
588
|
+
// Our "quantization tables" - the example JPEG tables,
|
|
589
|
+
// normalized so that the smallest value in each is 1.0.
|
|
590
|
+
// This gives us a relationship between error in DCT
|
|
591
|
+
// components
|
|
592
|
+
//
|
|
593
|
+
|
|
594
|
+
float _quantTableY[64];
|
|
595
|
+
float _quantTableCbCr[64];
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
//
|
|
601
|
+
// Single channel lossy DCT encoder
|
|
602
|
+
//
|
|
603
|
+
|
|
604
|
+
class DwaCompressor::LossyDctEncoder: public LossyDctEncoderBase
|
|
605
|
+
{
|
|
606
|
+
public:
|
|
607
|
+
|
|
608
|
+
LossyDctEncoder
|
|
609
|
+
(float quantBaseError,
|
|
610
|
+
std::vector<const char *> &rowPtrs,
|
|
611
|
+
char *packedAc,
|
|
612
|
+
char *packedDc,
|
|
613
|
+
const unsigned short *toNonlinear,
|
|
614
|
+
int width,
|
|
615
|
+
int height,
|
|
616
|
+
PixelType type)
|
|
617
|
+
:
|
|
618
|
+
LossyDctEncoderBase
|
|
619
|
+
(quantBaseError, packedAc, packedDc, toNonlinear, width, height)
|
|
620
|
+
{
|
|
621
|
+
_rowPtrs.push_back(rowPtrs);
|
|
622
|
+
_type.push_back(type);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
virtual ~LossyDctEncoder () {}
|
|
626
|
+
};
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
//
|
|
630
|
+
// RGB channel lossy DCT encoder
|
|
631
|
+
//
|
|
632
|
+
|
|
633
|
+
class DwaCompressor::LossyDctEncoderCsc: public LossyDctEncoderBase
|
|
634
|
+
{
|
|
635
|
+
public:
|
|
636
|
+
|
|
637
|
+
LossyDctEncoderCsc
|
|
638
|
+
(float quantBaseError,
|
|
639
|
+
std::vector<const char *> &rowPtrsR,
|
|
640
|
+
std::vector<const char *> &rowPtrsG,
|
|
641
|
+
std::vector<const char *> &rowPtrsB,
|
|
642
|
+
char *packedAc,
|
|
643
|
+
char *packedDc,
|
|
644
|
+
const unsigned short *toNonlinear,
|
|
645
|
+
int width,
|
|
646
|
+
int height,
|
|
647
|
+
PixelType typeR,
|
|
648
|
+
PixelType typeG,
|
|
649
|
+
PixelType typeB)
|
|
650
|
+
:
|
|
651
|
+
LossyDctEncoderBase
|
|
652
|
+
(quantBaseError, packedAc, packedDc, toNonlinear, width, height)
|
|
653
|
+
{
|
|
654
|
+
_type.push_back(typeR);
|
|
655
|
+
_type.push_back(typeG);
|
|
656
|
+
_type.push_back(typeB);
|
|
657
|
+
|
|
658
|
+
_rowPtrs.push_back(rowPtrsR);
|
|
659
|
+
_rowPtrs.push_back(rowPtrsG);
|
|
660
|
+
_rowPtrs.push_back(rowPtrsB);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
virtual ~LossyDctEncoderCsc () {}
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
// ==============================================================
|
|
668
|
+
//
|
|
669
|
+
// LossyDctDecoderBase
|
|
670
|
+
//
|
|
671
|
+
// --------------------------------------------------------------
|
|
672
|
+
|
|
673
|
+
DwaCompressor::LossyDctDecoderBase::LossyDctDecoderBase
|
|
674
|
+
(char *packedAc,
|
|
675
|
+
char *packedDc,
|
|
676
|
+
const unsigned short *toLinear,
|
|
677
|
+
int width,
|
|
678
|
+
int height)
|
|
679
|
+
:
|
|
680
|
+
_isNativeXdr(false),
|
|
681
|
+
_packedAcCount(0),
|
|
682
|
+
_packedDcCount(0),
|
|
683
|
+
_packedAc(packedAc),
|
|
684
|
+
_packedDc(packedDc),
|
|
685
|
+
_toLinear(toLinear),
|
|
686
|
+
_width(width),
|
|
687
|
+
_height(height)
|
|
688
|
+
{
|
|
689
|
+
if (_toLinear == 0)
|
|
690
|
+
_toLinear = dwaCompressorNoOp;
|
|
691
|
+
|
|
692
|
+
_isNativeXdr = GLOBAL_SYSTEM_LITTLE_ENDIAN;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
DwaCompressor::LossyDctDecoderBase::~LossyDctDecoderBase () {}
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
void
|
|
700
|
+
DwaCompressor::LossyDctDecoderBase::execute ()
|
|
701
|
+
{
|
|
702
|
+
int numComp = _rowPtrs.size();
|
|
703
|
+
int lastNonZero = 0;
|
|
704
|
+
int numBlocksX = (int) ceil ((float)_width / 8.0f);
|
|
705
|
+
int numBlocksY = (int) ceil ((float)_height / 8.0f);
|
|
706
|
+
int leftoverX = _width - (numBlocksX-1) * 8;
|
|
707
|
+
int leftoverY = _height - (numBlocksY-1) * 8;
|
|
708
|
+
|
|
709
|
+
int numFullBlocksX = (int)floor ((float)_width / 8.0f);
|
|
710
|
+
|
|
711
|
+
unsigned short tmpShortNative = 0;
|
|
712
|
+
unsigned short tmpShortXdr = 0;
|
|
713
|
+
const char *tmpConstCharPtr = 0;
|
|
714
|
+
|
|
715
|
+
unsigned short *currAcComp = (unsigned short *)_packedAc;
|
|
716
|
+
std::vector<unsigned short *> currDcComp (_rowPtrs.size());
|
|
717
|
+
std::vector<SimdAlignedBuffer64us> halfZigBlock (_rowPtrs.size());
|
|
718
|
+
|
|
719
|
+
if (_type.size() != _rowPtrs.size())
|
|
720
|
+
throw Iex::BaseExc ("Row pointers and types mismatch in count");
|
|
721
|
+
|
|
722
|
+
if ((_rowPtrs.size() != 3) && (_rowPtrs.size() != 1))
|
|
723
|
+
throw Iex::NoImplExc ("Only 1 and 3 channel encoding is supported");
|
|
724
|
+
|
|
725
|
+
_dctData.resize(numComp);
|
|
726
|
+
|
|
727
|
+
//
|
|
728
|
+
// Allocate a temp aligned buffer to hold a rows worth of full
|
|
729
|
+
// 8x8 half-float blocks
|
|
730
|
+
//
|
|
731
|
+
|
|
732
|
+
unsigned char *rowBlockHandle = new unsigned char
|
|
733
|
+
[numComp * numBlocksX * 64 * sizeof(unsigned short) + _SSE_ALIGNMENT];
|
|
734
|
+
|
|
735
|
+
unsigned short *rowBlock[3];
|
|
736
|
+
|
|
737
|
+
rowBlock[0] = (unsigned short*)rowBlockHandle;
|
|
738
|
+
|
|
739
|
+
for (int i = 0; i < _SSE_ALIGNMENT; ++i)
|
|
740
|
+
{
|
|
741
|
+
if (((size_t)(rowBlockHandle + i) & _SSE_ALIGNMENT_MASK) == 0)
|
|
742
|
+
rowBlock[0] = (unsigned short *)(rowBlockHandle + i);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
for (int comp = 1; comp < numComp; ++comp)
|
|
746
|
+
rowBlock[comp] = rowBlock[comp - 1] + numBlocksX * 64;
|
|
747
|
+
|
|
748
|
+
//
|
|
749
|
+
// Pack DC components together by common plane, so we can get
|
|
750
|
+
// a little more out of differencing them. We'll always have
|
|
751
|
+
// one component per block, so we can computed offsets.
|
|
752
|
+
//
|
|
753
|
+
|
|
754
|
+
currDcComp[0] = (unsigned short *)_packedDc;
|
|
755
|
+
|
|
756
|
+
for (unsigned int comp = 1; comp < numComp; ++comp)
|
|
757
|
+
currDcComp[comp] = currDcComp[comp - 1] + numBlocksX * numBlocksY;
|
|
758
|
+
|
|
759
|
+
for (int blocky = 0; blocky < numBlocksY; ++blocky)
|
|
760
|
+
{
|
|
761
|
+
int maxY = 8;
|
|
762
|
+
|
|
763
|
+
if (blocky == numBlocksY-1)
|
|
764
|
+
maxY = leftoverY;
|
|
765
|
+
|
|
766
|
+
int maxX = 8;
|
|
767
|
+
|
|
768
|
+
for (int blockx = 0; blockx < numBlocksX; ++blockx)
|
|
769
|
+
{
|
|
770
|
+
if (blockx == numBlocksX-1)
|
|
771
|
+
maxX = leftoverX;
|
|
772
|
+
|
|
773
|
+
//
|
|
774
|
+
// If we can detect that the block is constant values
|
|
775
|
+
// (all components only have DC values, and all AC is 0),
|
|
776
|
+
// we can do everything only on 1 value, instead of all
|
|
777
|
+
// 64.
|
|
778
|
+
//
|
|
779
|
+
// This won't really help for regular images, but it is
|
|
780
|
+
// meant more for layers with large swaths of black
|
|
781
|
+
//
|
|
782
|
+
|
|
783
|
+
bool blockIsConstant = true;
|
|
784
|
+
|
|
785
|
+
for (unsigned int comp = 0; comp < numComp; ++comp)
|
|
786
|
+
{
|
|
787
|
+
|
|
788
|
+
//
|
|
789
|
+
// DC component is stored separately
|
|
790
|
+
//
|
|
791
|
+
|
|
792
|
+
#ifdef IMF_HAVE_SSE2
|
|
793
|
+
{
|
|
794
|
+
__m128i *dst = (__m128i*)halfZigBlock[comp]._buffer;
|
|
795
|
+
|
|
796
|
+
dst[7] = _mm_setzero_si128();
|
|
797
|
+
dst[6] = _mm_setzero_si128();
|
|
798
|
+
dst[5] = _mm_setzero_si128();
|
|
799
|
+
dst[4] = _mm_setzero_si128();
|
|
800
|
+
dst[3] = _mm_setzero_si128();
|
|
801
|
+
dst[2] = _mm_setzero_si128();
|
|
802
|
+
dst[1] = _mm_setzero_si128();
|
|
803
|
+
dst[0] = _mm_insert_epi16
|
|
804
|
+
(_mm_setzero_si128(), *currDcComp[comp]++, 0);
|
|
805
|
+
}
|
|
806
|
+
#else /* IMF_HAVE_SSE2 */
|
|
807
|
+
|
|
808
|
+
memset (halfZigBlock[comp]._buffer, 0, 64 * 2);
|
|
809
|
+
halfZigBlock[comp]._buffer[0] = *currDcComp[comp]++;
|
|
810
|
+
|
|
811
|
+
#endif /* IMF_HAVE_SSE2 */
|
|
812
|
+
|
|
813
|
+
_packedDcCount++;
|
|
814
|
+
|
|
815
|
+
//
|
|
816
|
+
// UnRLE the AC. This will modify currAcComp
|
|
817
|
+
//
|
|
818
|
+
|
|
819
|
+
lastNonZero = unRleAc (currAcComp, halfZigBlock[comp]._buffer);
|
|
820
|
+
|
|
821
|
+
//
|
|
822
|
+
// Convert from XDR to NATIVE
|
|
823
|
+
//
|
|
824
|
+
|
|
825
|
+
if (!_isNativeXdr)
|
|
826
|
+
{
|
|
827
|
+
for (int i = 0; i < 64; ++i)
|
|
828
|
+
{
|
|
829
|
+
tmpShortXdr = halfZigBlock[comp]._buffer[i];
|
|
830
|
+
tmpConstCharPtr = (const char *)&tmpShortXdr;
|
|
831
|
+
|
|
832
|
+
Xdr::read<CharPtrIO> (tmpConstCharPtr, tmpShortNative);
|
|
833
|
+
|
|
834
|
+
halfZigBlock[comp]._buffer[i] = tmpShortNative;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
if (lastNonZero == 0)
|
|
839
|
+
{
|
|
840
|
+
//
|
|
841
|
+
// DC only case - AC components are all 0
|
|
842
|
+
//
|
|
843
|
+
|
|
844
|
+
half h;
|
|
845
|
+
|
|
846
|
+
h.setBits (halfZigBlock[comp]._buffer[0]);
|
|
847
|
+
_dctData[comp]._buffer[0] = (float)h;
|
|
848
|
+
|
|
849
|
+
dctInverse8x8DcOnly (_dctData[comp]._buffer);
|
|
850
|
+
}
|
|
851
|
+
else
|
|
852
|
+
{
|
|
853
|
+
//
|
|
854
|
+
// We have some AC components that are non-zero.
|
|
855
|
+
// Can't use the 'constant block' optimization
|
|
856
|
+
//
|
|
857
|
+
|
|
858
|
+
blockIsConstant = false;
|
|
859
|
+
|
|
860
|
+
//
|
|
861
|
+
// Un-Zig zag
|
|
862
|
+
//
|
|
863
|
+
|
|
864
|
+
(*fromHalfZigZag)
|
|
865
|
+
(halfZigBlock[comp]._buffer, _dctData[comp]._buffer);
|
|
866
|
+
|
|
867
|
+
//
|
|
868
|
+
// Zig-Zag indices in normal layout are as follows:
|
|
869
|
+
//
|
|
870
|
+
// 0 1 3 6 10 15 21 28
|
|
871
|
+
// 2 4 7 11 16 22 29 36
|
|
872
|
+
// 5 8 12 17 23 30 37 43
|
|
873
|
+
// 9 13 18 24 31 38 44 49
|
|
874
|
+
// 14 19 25 32 39 45 50 54
|
|
875
|
+
// 20 26 33 40 46 51 55 58
|
|
876
|
+
// 27 34 41 47 52 56 59 61
|
|
877
|
+
// 35 42 48 53 57 60 62 63
|
|
878
|
+
//
|
|
879
|
+
// If lastNonZero is less than the first item on
|
|
880
|
+
// each row, we know that the whole row is zero and
|
|
881
|
+
// can be skipped in the row-oriented part of the
|
|
882
|
+
// iDCT.
|
|
883
|
+
//
|
|
884
|
+
// The unrolled logic here is:
|
|
885
|
+
//
|
|
886
|
+
// if lastNonZero < rowStartIdx[i],
|
|
887
|
+
// zeroedRows = rowsEmpty[i]
|
|
888
|
+
//
|
|
889
|
+
// where:
|
|
890
|
+
//
|
|
891
|
+
// const int rowStartIdx[] = {2, 5, 9, 14, 20, 27, 35};
|
|
892
|
+
// const int rowsEmpty[] = {7, 6, 5, 4, 3, 2, 1};
|
|
893
|
+
//
|
|
894
|
+
|
|
895
|
+
if (lastNonZero < 2)
|
|
896
|
+
dctInverse8x8_7(_dctData[comp]._buffer);
|
|
897
|
+
else if (lastNonZero < 5)
|
|
898
|
+
dctInverse8x8_6(_dctData[comp]._buffer);
|
|
899
|
+
else if (lastNonZero < 9)
|
|
900
|
+
dctInverse8x8_5(_dctData[comp]._buffer);
|
|
901
|
+
else if (lastNonZero < 14)
|
|
902
|
+
dctInverse8x8_4(_dctData[comp]._buffer);
|
|
903
|
+
else if (lastNonZero < 20)
|
|
904
|
+
dctInverse8x8_3(_dctData[comp]._buffer);
|
|
905
|
+
else if (lastNonZero < 27)
|
|
906
|
+
dctInverse8x8_2(_dctData[comp]._buffer);
|
|
907
|
+
else if (lastNonZero < 35)
|
|
908
|
+
dctInverse8x8_1(_dctData[comp]._buffer);
|
|
909
|
+
else
|
|
910
|
+
dctInverse8x8_0(_dctData[comp]._buffer);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
//
|
|
915
|
+
// Perform the CSC
|
|
916
|
+
//
|
|
917
|
+
|
|
918
|
+
if (numComp == 3)
|
|
919
|
+
{
|
|
920
|
+
if (!blockIsConstant)
|
|
921
|
+
{
|
|
922
|
+
csc709Inverse64 (_dctData[0]._buffer,
|
|
923
|
+
_dctData[1]._buffer,
|
|
924
|
+
_dctData[2]._buffer);
|
|
925
|
+
|
|
926
|
+
}
|
|
927
|
+
else
|
|
928
|
+
{
|
|
929
|
+
csc709Inverse (_dctData[0]._buffer[0],
|
|
930
|
+
_dctData[1]._buffer[0],
|
|
931
|
+
_dctData[2]._buffer[0]);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
//
|
|
936
|
+
// Float -> Half conversion.
|
|
937
|
+
//
|
|
938
|
+
// If the block has a constant value, just convert the first pixel.
|
|
939
|
+
//
|
|
940
|
+
|
|
941
|
+
for (unsigned int comp = 0; comp < numComp; ++comp)
|
|
942
|
+
{
|
|
943
|
+
if (!blockIsConstant)
|
|
944
|
+
{
|
|
945
|
+
(*convertFloatToHalf64)
|
|
946
|
+
(&rowBlock[comp][blockx*64], _dctData[comp]._buffer);
|
|
947
|
+
}
|
|
948
|
+
else
|
|
949
|
+
{
|
|
950
|
+
#if IMF_HAVE_SSE2
|
|
951
|
+
|
|
952
|
+
__m128i *dst = (__m128i*)&rowBlock[comp][blockx*64];
|
|
953
|
+
|
|
954
|
+
dst[0] = _mm_set1_epi16
|
|
955
|
+
(((half)_dctData[comp]._buffer[0]).bits());
|
|
956
|
+
|
|
957
|
+
dst[1] = dst[0];
|
|
958
|
+
dst[2] = dst[0];
|
|
959
|
+
dst[3] = dst[0];
|
|
960
|
+
dst[4] = dst[0];
|
|
961
|
+
dst[5] = dst[0];
|
|
962
|
+
dst[6] = dst[0];
|
|
963
|
+
dst[7] = dst[0];
|
|
964
|
+
|
|
965
|
+
#else /* IMF_HAVE_SSE2 */
|
|
966
|
+
|
|
967
|
+
unsigned short *dst = &rowBlock[comp][blockx*64];
|
|
968
|
+
|
|
969
|
+
dst[0] = ((half)_dctData[comp]._buffer[0]).bits();
|
|
970
|
+
|
|
971
|
+
for (int i = 1; i < 64; ++i)
|
|
972
|
+
{
|
|
973
|
+
dst[i] = dst[0];
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
#endif /* IMF_HAVE_SSE2 */
|
|
977
|
+
} // blockIsConstant
|
|
978
|
+
} // comp
|
|
979
|
+
} // blockx
|
|
980
|
+
|
|
981
|
+
//
|
|
982
|
+
// At this point, we have half-float nonlinear value blocked
|
|
983
|
+
// in rowBlock[][]. We need to unblock the data, transfer
|
|
984
|
+
// back to linear, and write the results in the _rowPtrs[].
|
|
985
|
+
//
|
|
986
|
+
// There is a fast-path for aligned rows, which helps
|
|
987
|
+
// things a little. Since this fast path is only valid
|
|
988
|
+
// for full 8-element wide blocks, the partial x blocks
|
|
989
|
+
// are broken into a separate loop below.
|
|
990
|
+
//
|
|
991
|
+
// At the moment, the fast path requires:
|
|
992
|
+
// * sse support
|
|
993
|
+
// * aligned row pointers
|
|
994
|
+
// * full 8-element wide blocks
|
|
995
|
+
//
|
|
996
|
+
|
|
997
|
+
for (int comp = 0; comp < numComp; ++comp)
|
|
998
|
+
{
|
|
999
|
+
//
|
|
1000
|
+
// Test if we can use the fast path
|
|
1001
|
+
//
|
|
1002
|
+
|
|
1003
|
+
#ifdef IMF_HAVE_SSE2
|
|
1004
|
+
|
|
1005
|
+
bool fastPath = true;
|
|
1006
|
+
|
|
1007
|
+
for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
|
|
1008
|
+
{
|
|
1009
|
+
if ((size_t)_rowPtrs[comp][y] & _SSE_ALIGNMENT_MASK)
|
|
1010
|
+
fastPath = false;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
if (fastPath)
|
|
1014
|
+
{
|
|
1015
|
+
//
|
|
1016
|
+
// Handle all the full X blocks, in a fast path with sse2 and
|
|
1017
|
+
// aligned row pointers
|
|
1018
|
+
//
|
|
1019
|
+
|
|
1020
|
+
for (int y=8*blocky; y<8*blocky+maxY; ++y)
|
|
1021
|
+
{
|
|
1022
|
+
__m128i *dst = (__m128i *)_rowPtrs[comp][y];
|
|
1023
|
+
__m128i *src = (__m128i *)&rowBlock[comp][(y & 0x7) * 8];
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
for (int blockx = 0; blockx < numFullBlocksX; ++blockx)
|
|
1027
|
+
{
|
|
1028
|
+
//
|
|
1029
|
+
// These may need some twiddling.
|
|
1030
|
+
// Run with multiples of 8
|
|
1031
|
+
//
|
|
1032
|
+
|
|
1033
|
+
_mm_prefetch ((char *)(src + 16), _MM_HINT_NTA);
|
|
1034
|
+
|
|
1035
|
+
unsigned short i0 = _mm_extract_epi16 (*src, 0);
|
|
1036
|
+
unsigned short i1 = _mm_extract_epi16 (*src, 1);
|
|
1037
|
+
unsigned short i2 = _mm_extract_epi16 (*src, 2);
|
|
1038
|
+
unsigned short i3 = _mm_extract_epi16 (*src, 3);
|
|
1039
|
+
|
|
1040
|
+
unsigned short i4 = _mm_extract_epi16 (*src, 4);
|
|
1041
|
+
unsigned short i5 = _mm_extract_epi16 (*src, 5);
|
|
1042
|
+
unsigned short i6 = _mm_extract_epi16 (*src, 6);
|
|
1043
|
+
unsigned short i7 = _mm_extract_epi16 (*src, 7);
|
|
1044
|
+
|
|
1045
|
+
i0 = _toLinear[i0];
|
|
1046
|
+
i1 = _toLinear[i1];
|
|
1047
|
+
i2 = _toLinear[i2];
|
|
1048
|
+
i3 = _toLinear[i3];
|
|
1049
|
+
|
|
1050
|
+
i4 = _toLinear[i4];
|
|
1051
|
+
i5 = _toLinear[i5];
|
|
1052
|
+
i6 = _toLinear[i6];
|
|
1053
|
+
i7 = _toLinear[i7];
|
|
1054
|
+
|
|
1055
|
+
*dst = _mm_insert_epi16 (_mm_setzero_si128(), i0, 0);
|
|
1056
|
+
*dst = _mm_insert_epi16 (*dst, i1, 1);
|
|
1057
|
+
*dst = _mm_insert_epi16 (*dst, i2, 2);
|
|
1058
|
+
*dst = _mm_insert_epi16 (*dst, i3, 3);
|
|
1059
|
+
|
|
1060
|
+
*dst = _mm_insert_epi16 (*dst, i4, 4);
|
|
1061
|
+
*dst = _mm_insert_epi16 (*dst, i5, 5);
|
|
1062
|
+
*dst = _mm_insert_epi16 (*dst, i6, 6);
|
|
1063
|
+
*dst = _mm_insert_epi16 (*dst, i7, 7);
|
|
1064
|
+
|
|
1065
|
+
src += 8;
|
|
1066
|
+
dst++;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
else
|
|
1071
|
+
{
|
|
1072
|
+
|
|
1073
|
+
#endif /* IMF_HAVE_SSE2 */
|
|
1074
|
+
|
|
1075
|
+
//
|
|
1076
|
+
// Basic scalar kinda slow path for handling the full X blocks
|
|
1077
|
+
//
|
|
1078
|
+
|
|
1079
|
+
for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
|
|
1080
|
+
{
|
|
1081
|
+
unsigned short *dst = (unsigned short *)_rowPtrs[comp][y];
|
|
1082
|
+
|
|
1083
|
+
for (int blockx = 0; blockx < numFullBlocksX; ++blockx)
|
|
1084
|
+
{
|
|
1085
|
+
unsigned short *src =
|
|
1086
|
+
&rowBlock[comp][blockx * 64 + ((y & 0x7) * 8)];
|
|
1087
|
+
|
|
1088
|
+
dst[0] = _toLinear[src[0]];
|
|
1089
|
+
dst[1] = _toLinear[src[1]];
|
|
1090
|
+
dst[2] = _toLinear[src[2]];
|
|
1091
|
+
dst[3] = _toLinear[src[3]];
|
|
1092
|
+
|
|
1093
|
+
dst[4] = _toLinear[src[4]];
|
|
1094
|
+
dst[5] = _toLinear[src[5]];
|
|
1095
|
+
dst[6] = _toLinear[src[6]];
|
|
1096
|
+
dst[7] = _toLinear[src[7]];
|
|
1097
|
+
|
|
1098
|
+
dst += 8;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
#ifdef IMF_HAVE_SSE2
|
|
1103
|
+
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
#endif /* IMF_HAVE_SSE2 */
|
|
1107
|
+
|
|
1108
|
+
//
|
|
1109
|
+
// If we have partial X blocks, deal with all those now
|
|
1110
|
+
// Since this should be minimal work, there currently
|
|
1111
|
+
// is only one path that should work for everyone.
|
|
1112
|
+
//
|
|
1113
|
+
|
|
1114
|
+
if (numFullBlocksX != numBlocksX)
|
|
1115
|
+
{
|
|
1116
|
+
for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
|
|
1117
|
+
{
|
|
1118
|
+
unsigned short *src = (unsigned short *)
|
|
1119
|
+
&rowBlock[comp][numFullBlocksX * 64 + ((y & 0x7) * 8)];
|
|
1120
|
+
|
|
1121
|
+
unsigned short *dst = (unsigned short *)_rowPtrs[comp][y];
|
|
1122
|
+
|
|
1123
|
+
dst += 8 * numFullBlocksX;
|
|
1124
|
+
|
|
1125
|
+
for (int x = 0; x < maxX; ++x)
|
|
1126
|
+
{
|
|
1127
|
+
*dst++ = _toLinear[*src++];
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
} // comp
|
|
1132
|
+
} // blocky
|
|
1133
|
+
|
|
1134
|
+
//
|
|
1135
|
+
// Walk over all the channels that are of type FLOAT.
|
|
1136
|
+
// Convert from HALF XDR back to FLOAT XDR.
|
|
1137
|
+
//
|
|
1138
|
+
|
|
1139
|
+
for (unsigned int chan = 0; chan < numComp; ++chan)
|
|
1140
|
+
{
|
|
1141
|
+
|
|
1142
|
+
if (_type[chan] != FLOAT)
|
|
1143
|
+
continue;
|
|
1144
|
+
|
|
1145
|
+
std::vector<unsigned short> halfXdr (_width);
|
|
1146
|
+
|
|
1147
|
+
for (int y=0; y<_height; ++y)
|
|
1148
|
+
{
|
|
1149
|
+
char *floatXdrPtr = _rowPtrs[chan][y];
|
|
1150
|
+
|
|
1151
|
+
memcpy(&halfXdr[0], floatXdrPtr, _width*sizeof(unsigned short));
|
|
1152
|
+
|
|
1153
|
+
const char *halfXdrPtr = (const char *)(&halfXdr[0]);
|
|
1154
|
+
|
|
1155
|
+
for (int x=0; x<_width; ++x)
|
|
1156
|
+
{
|
|
1157
|
+
half tmpHalf;
|
|
1158
|
+
|
|
1159
|
+
Xdr::read<CharPtrIO> (halfXdrPtr, tmpHalf);
|
|
1160
|
+
Xdr::write<CharPtrIO> (floatXdrPtr, (float)tmpHalf);
|
|
1161
|
+
|
|
1162
|
+
//
|
|
1163
|
+
// Xdr::write and Xdr::read will advance the ptrs
|
|
1164
|
+
//
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
delete[] rowBlockHandle;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
//
|
|
1174
|
+
// Un-RLE the packed AC components into
|
|
1175
|
+
// a half buffer. The half block should
|
|
1176
|
+
// be the full 8x8 block (in zig-zag order
|
|
1177
|
+
// still), not the first AC component.
|
|
1178
|
+
//
|
|
1179
|
+
// currAcComp is advanced as bytes are decoded.
|
|
1180
|
+
//
|
|
1181
|
+
// This returns the index of the last non-zero
|
|
1182
|
+
// value in the buffer - with the index into zig zag
|
|
1183
|
+
// order data. If we return 0, we have DC only data.
|
|
1184
|
+
//
|
|
1185
|
+
// This is assuminging that halfZigBlock is zero'ed
|
|
1186
|
+
// prior to calling
|
|
1187
|
+
//
|
|
1188
|
+
|
|
1189
|
+
int
|
|
1190
|
+
DwaCompressor::LossyDctDecoderBase::unRleAc
|
|
1191
|
+
(unsigned short *&currAcComp,
|
|
1192
|
+
unsigned short *halfZigBlock)
|
|
1193
|
+
{
|
|
1194
|
+
//
|
|
1195
|
+
// Un-RLE the RLE'd blocks. If we find an item whose
|
|
1196
|
+
// high byte is 0xff, then insert the number of 0's
|
|
1197
|
+
// as indicated by the low byte.
|
|
1198
|
+
//
|
|
1199
|
+
// Otherwise, just copy the number verbaitm.
|
|
1200
|
+
//
|
|
1201
|
+
|
|
1202
|
+
int lastNonZero = 0;
|
|
1203
|
+
int dctComp = 1;
|
|
1204
|
+
|
|
1205
|
+
//
|
|
1206
|
+
// Start with a zero'ed block, so we don't have to
|
|
1207
|
+
// write when we hit a run symbol
|
|
1208
|
+
//
|
|
1209
|
+
|
|
1210
|
+
while (dctComp < 64)
|
|
1211
|
+
{
|
|
1212
|
+
if (*currAcComp == 0xff00)
|
|
1213
|
+
{
|
|
1214
|
+
//
|
|
1215
|
+
// End of block
|
|
1216
|
+
//
|
|
1217
|
+
|
|
1218
|
+
dctComp = 64;
|
|
1219
|
+
|
|
1220
|
+
}
|
|
1221
|
+
else if ((*currAcComp) >> 8 == 0xff)
|
|
1222
|
+
{
|
|
1223
|
+
//
|
|
1224
|
+
// Run detected! Insert 0's.
|
|
1225
|
+
//
|
|
1226
|
+
// Since the block has been zeroed, just advance the ptr
|
|
1227
|
+
//
|
|
1228
|
+
|
|
1229
|
+
dctComp += (*currAcComp) & 0xff;
|
|
1230
|
+
}
|
|
1231
|
+
else
|
|
1232
|
+
{
|
|
1233
|
+
//
|
|
1234
|
+
// Not a run, just copy over the value
|
|
1235
|
+
//
|
|
1236
|
+
|
|
1237
|
+
lastNonZero = dctComp;
|
|
1238
|
+
halfZigBlock[dctComp] = *currAcComp;
|
|
1239
|
+
|
|
1240
|
+
dctComp++;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
_packedAcCount++;
|
|
1244
|
+
currAcComp++;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
return lastNonZero;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
// ==============================================================
|
|
1252
|
+
//
|
|
1253
|
+
// LossyDctEncoderBase
|
|
1254
|
+
//
|
|
1255
|
+
// --------------------------------------------------------------
|
|
1256
|
+
|
|
1257
|
+
DwaCompressor::LossyDctEncoderBase::LossyDctEncoderBase
|
|
1258
|
+
(float quantBaseError,
|
|
1259
|
+
char *packedAc,
|
|
1260
|
+
char *packedDc,
|
|
1261
|
+
const unsigned short *toNonlinear,
|
|
1262
|
+
int width,
|
|
1263
|
+
int height)
|
|
1264
|
+
:
|
|
1265
|
+
_quantBaseError(quantBaseError),
|
|
1266
|
+
_width(width),
|
|
1267
|
+
_height(height),
|
|
1268
|
+
_toNonlinear(toNonlinear),
|
|
1269
|
+
_numAcComp(0),
|
|
1270
|
+
_numDcComp(0),
|
|
1271
|
+
_packedAc(packedAc),
|
|
1272
|
+
_packedDc(packedDc)
|
|
1273
|
+
{
|
|
1274
|
+
//
|
|
1275
|
+
// Here, we take the generic JPEG quantization tables and
|
|
1276
|
+
// normalize them by the smallest component in each table.
|
|
1277
|
+
// This gives us a relationship amongst the DCT components,
|
|
1278
|
+
// in terms of how sensitive each component is to
|
|
1279
|
+
// error.
|
|
1280
|
+
//
|
|
1281
|
+
// A higher normalized value means we can quantize more,
|
|
1282
|
+
// and a small normalized value means we can quantize less.
|
|
1283
|
+
//
|
|
1284
|
+
// Eventually, we will want an acceptable quantization
|
|
1285
|
+
// error range for each component. We find this by
|
|
1286
|
+
// multiplying some user-specified level (_quantBaseError)
|
|
1287
|
+
// by the normalized table (_quantTableY, _quantTableCbCr) to
|
|
1288
|
+
// find the acceptable quantization error range.
|
|
1289
|
+
//
|
|
1290
|
+
// The quantization table is not needed for decoding, and
|
|
1291
|
+
// is not transmitted. So, if you want to get really fancy,
|
|
1292
|
+
// you could derive some content-dependent quantization
|
|
1293
|
+
// table, and the decoder would not need to be changed. But,
|
|
1294
|
+
// for now, we'll just use statice quantization tables.
|
|
1295
|
+
//
|
|
1296
|
+
|
|
1297
|
+
int jpegQuantTableY[] =
|
|
1298
|
+
{
|
|
1299
|
+
16, 11, 10, 16, 24, 40, 51, 61,
|
|
1300
|
+
12, 12, 14, 19, 26, 58, 60, 55,
|
|
1301
|
+
14, 13, 16, 24, 40, 57, 69, 56,
|
|
1302
|
+
14, 17, 22, 29, 51, 87, 80, 62,
|
|
1303
|
+
18, 22, 37, 56, 68, 109, 103, 77,
|
|
1304
|
+
24, 35, 55, 64, 81, 104, 113, 92,
|
|
1305
|
+
49, 64, 78, 87, 103, 121, 120, 101,
|
|
1306
|
+
72, 92, 95, 98, 112, 100, 103, 99
|
|
1307
|
+
};
|
|
1308
|
+
|
|
1309
|
+
int jpegQuantTableYMin = 10;
|
|
1310
|
+
|
|
1311
|
+
int jpegQuantTableCbCr[] =
|
|
1312
|
+
{
|
|
1313
|
+
17, 18, 24, 47, 99, 99, 99, 99,
|
|
1314
|
+
18, 21, 26, 66, 99, 99, 99, 99,
|
|
1315
|
+
24, 26, 56, 99, 99, 99, 99, 99,
|
|
1316
|
+
47, 66, 99, 99, 99, 99, 99, 99,
|
|
1317
|
+
99, 99, 99, 99, 99, 99, 99, 99,
|
|
1318
|
+
99, 99, 99, 99, 99, 99, 99, 99,
|
|
1319
|
+
99, 99, 99, 99, 99, 99, 99, 99,
|
|
1320
|
+
99, 99, 99, 99, 99, 99, 99, 99
|
|
1321
|
+
};
|
|
1322
|
+
|
|
1323
|
+
int jpegQuantTableCbCrMin = 17;
|
|
1324
|
+
|
|
1325
|
+
for (int idx = 0; idx < 64; ++idx)
|
|
1326
|
+
{
|
|
1327
|
+
_quantTableY[idx] = static_cast<float> (jpegQuantTableY[idx]) /
|
|
1328
|
+
static_cast<float> (jpegQuantTableYMin);
|
|
1329
|
+
|
|
1330
|
+
_quantTableCbCr[idx] = static_cast<float> (jpegQuantTableCbCr[idx]) /
|
|
1331
|
+
static_cast<float> (jpegQuantTableCbCrMin);
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
if (_quantBaseError < 0)
|
|
1335
|
+
quantBaseError = 0;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
DwaCompressor::LossyDctEncoderBase::~LossyDctEncoderBase ()
|
|
1340
|
+
{
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
//
|
|
1345
|
+
// Given three channels of source data, encoding by first applying
|
|
1346
|
+
// a color space conversion to a YCbCr space. Otherwise, if we only
|
|
1347
|
+
// have one channel, just encode it as is.
|
|
1348
|
+
//
|
|
1349
|
+
// Other numbers of channels are somewhat unexpected at this point,
|
|
1350
|
+
// and will throw an exception.
|
|
1351
|
+
//
|
|
1352
|
+
|
|
1353
|
+
void
|
|
1354
|
+
DwaCompressor::LossyDctEncoderBase::execute ()
|
|
1355
|
+
{
|
|
1356
|
+
int numBlocksX = (int)ceil ((float)_width / 8.0f);
|
|
1357
|
+
int numBlocksY = (int)ceil ((float)_height/ 8.0f);
|
|
1358
|
+
|
|
1359
|
+
half halfZigCoef[64];
|
|
1360
|
+
half halfCoef[64];
|
|
1361
|
+
|
|
1362
|
+
std::vector<unsigned short *> currDcComp (_rowPtrs.size());
|
|
1363
|
+
unsigned short *currAcComp = (unsigned short *)_packedAc;
|
|
1364
|
+
|
|
1365
|
+
_dctData.resize (_rowPtrs.size());
|
|
1366
|
+
_numAcComp = 0;
|
|
1367
|
+
_numDcComp = 0;
|
|
1368
|
+
|
|
1369
|
+
assert (_type.size() == _rowPtrs.size());
|
|
1370
|
+
assert ((_rowPtrs.size() == 3) || (_rowPtrs.size() == 1));
|
|
1371
|
+
|
|
1372
|
+
//
|
|
1373
|
+
// Allocate a temp half buffer to quantize into for
|
|
1374
|
+
// any FLOAT source channels.
|
|
1375
|
+
//
|
|
1376
|
+
|
|
1377
|
+
int tmpHalfBufferElements = 0;
|
|
1378
|
+
|
|
1379
|
+
for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
|
|
1380
|
+
if (_type[chan] == FLOAT)
|
|
1381
|
+
tmpHalfBufferElements += _width * _height;
|
|
1382
|
+
|
|
1383
|
+
std::vector<unsigned short> tmpHalfBuffer (tmpHalfBufferElements);
|
|
1384
|
+
|
|
1385
|
+
char *tmpHalfBufferPtr = 0;
|
|
1386
|
+
|
|
1387
|
+
if (tmpHalfBufferElements)
|
|
1388
|
+
tmpHalfBufferPtr = (char *)&tmpHalfBuffer[0];
|
|
1389
|
+
|
|
1390
|
+
//
|
|
1391
|
+
// Run over all the float scanlines, quantizing,
|
|
1392
|
+
// and re-assigning _rowPtr[y]. We need to translate
|
|
1393
|
+
// FLOAT XDR to HALF XDR.
|
|
1394
|
+
//
|
|
1395
|
+
|
|
1396
|
+
for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
|
|
1397
|
+
{
|
|
1398
|
+
if (_type[chan] != FLOAT)
|
|
1399
|
+
continue;
|
|
1400
|
+
|
|
1401
|
+
for (int y = 0; y < _height; ++y)
|
|
1402
|
+
{
|
|
1403
|
+
float src = 0;
|
|
1404
|
+
const char *srcXdr = _rowPtrs[chan][y];
|
|
1405
|
+
char *dstXdr = tmpHalfBufferPtr;
|
|
1406
|
+
|
|
1407
|
+
for (int x = 0; x < _width; ++x)
|
|
1408
|
+
{
|
|
1409
|
+
|
|
1410
|
+
Xdr::read<CharPtrIO> (srcXdr, src);
|
|
1411
|
+
Xdr::write<CharPtrIO> (dstXdr, ((half)src).bits());
|
|
1412
|
+
|
|
1413
|
+
//
|
|
1414
|
+
// Xdr::read and Xdr::write will advance the ptr
|
|
1415
|
+
//
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
_rowPtrs[chan][y] = (const char *)tmpHalfBufferPtr;
|
|
1419
|
+
tmpHalfBufferPtr += _width * sizeof (unsigned short);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
//
|
|
1424
|
+
// Pack DC components together by common plane, so we can get
|
|
1425
|
+
// a little more out of differencing them. We'll always have
|
|
1426
|
+
// one component per block, so we can computed offsets.
|
|
1427
|
+
//
|
|
1428
|
+
|
|
1429
|
+
currDcComp[0] = (unsigned short *)_packedDc;
|
|
1430
|
+
|
|
1431
|
+
for (unsigned int chan = 1; chan < _rowPtrs.size(); ++chan)
|
|
1432
|
+
currDcComp[chan] = currDcComp[chan-1] + numBlocksX * numBlocksY;
|
|
1433
|
+
|
|
1434
|
+
for (int blocky = 0; blocky < numBlocksY; ++blocky)
|
|
1435
|
+
{
|
|
1436
|
+
for (int blockx = 0; blockx < numBlocksX; ++blockx)
|
|
1437
|
+
{
|
|
1438
|
+
half h;
|
|
1439
|
+
unsigned short tmpShortXdr, tmpShortNative;
|
|
1440
|
+
char *tmpCharPtr;
|
|
1441
|
+
|
|
1442
|
+
for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
|
|
1443
|
+
{
|
|
1444
|
+
//
|
|
1445
|
+
// Break the source into 8x8 blocks. If we don't
|
|
1446
|
+
// fit at the edges, mirror.
|
|
1447
|
+
//
|
|
1448
|
+
// Also, convert from linear to nonlinear representation.
|
|
1449
|
+
// Our source is assumed to be XDR, and we need to convert
|
|
1450
|
+
// to NATIVE prior to converting to float.
|
|
1451
|
+
//
|
|
1452
|
+
// If we're converting linear -> nonlinear, assume that the
|
|
1453
|
+
// XDR -> NATIVE conversion is built into the lookup. Otherwise,
|
|
1454
|
+
// we'll need to explicitly do it.
|
|
1455
|
+
//
|
|
1456
|
+
|
|
1457
|
+
for (int y = 0; y < 8; ++y)
|
|
1458
|
+
{
|
|
1459
|
+
for (int x = 0; x < 8; ++x)
|
|
1460
|
+
{
|
|
1461
|
+
int vx = 8 * blockx + x;
|
|
1462
|
+
int vy = 8 * blocky + y;
|
|
1463
|
+
|
|
1464
|
+
if (vx >= _width)
|
|
1465
|
+
vx = _width - (vx - (_width - 1));
|
|
1466
|
+
|
|
1467
|
+
if (vx < 0) vx = _width-1;
|
|
1468
|
+
|
|
1469
|
+
if (vy >=_height)
|
|
1470
|
+
vy = _height - (vy - (_height - 1));
|
|
1471
|
+
|
|
1472
|
+
if (vy < 0) vy = _height-1;
|
|
1473
|
+
|
|
1474
|
+
tmpShortXdr =
|
|
1475
|
+
((const unsigned short *)(_rowPtrs[chan])[vy])[vx];
|
|
1476
|
+
|
|
1477
|
+
if (_toNonlinear)
|
|
1478
|
+
{
|
|
1479
|
+
h.setBits (_toNonlinear[tmpShortXdr]);
|
|
1480
|
+
}
|
|
1481
|
+
else
|
|
1482
|
+
{
|
|
1483
|
+
const char *tmpConstCharPtr =
|
|
1484
|
+
(const char *)(&tmpShortXdr);
|
|
1485
|
+
|
|
1486
|
+
Xdr::read<CharPtrIO>
|
|
1487
|
+
(tmpConstCharPtr, tmpShortNative);
|
|
1488
|
+
|
|
1489
|
+
h.setBits(tmpShortNative);
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
_dctData[chan]._buffer[y * 8 + x] = (float)h;
|
|
1493
|
+
} // x
|
|
1494
|
+
} // y
|
|
1495
|
+
} // chan
|
|
1496
|
+
|
|
1497
|
+
//
|
|
1498
|
+
// Color space conversion
|
|
1499
|
+
//
|
|
1500
|
+
|
|
1501
|
+
if (_rowPtrs.size() == 3)
|
|
1502
|
+
{
|
|
1503
|
+
csc709Forward64 (_dctData[0]._buffer,
|
|
1504
|
+
_dctData[1]._buffer,
|
|
1505
|
+
_dctData[2]._buffer);
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
|
|
1509
|
+
{
|
|
1510
|
+
//
|
|
1511
|
+
// Forward DCT
|
|
1512
|
+
//
|
|
1513
|
+
|
|
1514
|
+
dctForward8x8(_dctData[chan]._buffer);
|
|
1515
|
+
|
|
1516
|
+
//
|
|
1517
|
+
// Quantize to half, and zigzag
|
|
1518
|
+
//
|
|
1519
|
+
|
|
1520
|
+
if (chan == 0)
|
|
1521
|
+
{
|
|
1522
|
+
for (int i = 0; i < 64; ++i)
|
|
1523
|
+
{
|
|
1524
|
+
halfCoef[i] =
|
|
1525
|
+
quantize ((half)_dctData[chan]._buffer[i],
|
|
1526
|
+
_quantBaseError*_quantTableY[i]);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
else
|
|
1530
|
+
{
|
|
1531
|
+
for (int i = 0; i < 64; ++i)
|
|
1532
|
+
{
|
|
1533
|
+
halfCoef[i] =
|
|
1534
|
+
quantize ((half)_dctData[chan]._buffer[i],
|
|
1535
|
+
_quantBaseError*_quantTableCbCr[i]);
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
toZigZag (halfZigCoef, halfCoef);
|
|
1540
|
+
|
|
1541
|
+
//
|
|
1542
|
+
// Convert from NATIVE back to XDR, before we write out
|
|
1543
|
+
//
|
|
1544
|
+
|
|
1545
|
+
for (int i = 0; i < 64; ++i)
|
|
1546
|
+
{
|
|
1547
|
+
tmpCharPtr = (char *)&tmpShortXdr;
|
|
1548
|
+
Xdr::write<CharPtrIO>(tmpCharPtr, halfZigCoef[i].bits());
|
|
1549
|
+
halfZigCoef[i].setBits(tmpShortXdr);
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
//
|
|
1553
|
+
// Save the DC component separately, to be compressed on
|
|
1554
|
+
// its own.
|
|
1555
|
+
//
|
|
1556
|
+
|
|
1557
|
+
*currDcComp[chan]++ = halfZigCoef[0].bits();
|
|
1558
|
+
_numDcComp++;
|
|
1559
|
+
|
|
1560
|
+
//
|
|
1561
|
+
// Then RLE the AC components (which will record the count
|
|
1562
|
+
// of the resulting number of items)
|
|
1563
|
+
//
|
|
1564
|
+
|
|
1565
|
+
rleAc (halfZigCoef, currAcComp);
|
|
1566
|
+
} // chan
|
|
1567
|
+
} // blockx
|
|
1568
|
+
} // blocky
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
//
|
|
1573
|
+
// Reorder from zig-zag order to normal ordering
|
|
1574
|
+
//
|
|
1575
|
+
|
|
1576
|
+
void
|
|
1577
|
+
DwaCompressor::LossyDctEncoderBase::toZigZag (half *dst, half *src)
|
|
1578
|
+
{
|
|
1579
|
+
const int remap[] =
|
|
1580
|
+
{
|
|
1581
|
+
0,
|
|
1582
|
+
1, 8,
|
|
1583
|
+
16, 9, 2,
|
|
1584
|
+
3, 10, 17, 24,
|
|
1585
|
+
32, 25, 18, 11, 4,
|
|
1586
|
+
5, 12, 19, 26, 33, 40,
|
|
1587
|
+
48, 41, 34, 27, 20, 13, 6,
|
|
1588
|
+
7, 14, 21, 28, 35, 42, 49, 56,
|
|
1589
|
+
57, 50, 43, 36, 29, 22, 15,
|
|
1590
|
+
23, 30, 37, 44, 51, 58,
|
|
1591
|
+
59, 52, 45, 38, 31,
|
|
1592
|
+
39, 46, 53, 60,
|
|
1593
|
+
61, 54, 47,
|
|
1594
|
+
55, 62,
|
|
1595
|
+
63
|
|
1596
|
+
};
|
|
1597
|
+
|
|
1598
|
+
for (int i=0; i<64; ++i)
|
|
1599
|
+
dst[i] = src[remap[i]];
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
|
|
1603
|
+
//
|
|
1604
|
+
// Precomputing the bit count runs faster than using
|
|
1605
|
+
// the builtin instruction, at least in one case..
|
|
1606
|
+
//
|
|
1607
|
+
// Precomputing 8-bits is no slower than 16-bits,
|
|
1608
|
+
// and saves a fair bit of overhead..
|
|
1609
|
+
//
|
|
1610
|
+
|
|
1611
|
+
int
|
|
1612
|
+
DwaCompressor::LossyDctEncoderBase::countSetBits (unsigned short src)
|
|
1613
|
+
{
|
|
1614
|
+
static const unsigned short numBitsSet[256] =
|
|
1615
|
+
{
|
|
1616
|
+
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
|
1617
|
+
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
1618
|
+
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
1619
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
1620
|
+
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
1621
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
1622
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
1623
|
+
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
1624
|
+
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
1625
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
1626
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
1627
|
+
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
1628
|
+
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
1629
|
+
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
1630
|
+
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
1631
|
+
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
|
|
1632
|
+
};
|
|
1633
|
+
|
|
1634
|
+
return numBitsSet[src & 0xff] + numBitsSet[src >> 8];
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
|
|
1638
|
+
//
|
|
1639
|
+
// Take a DCT coefficient, as well as an acceptable error. Search
|
|
1640
|
+
// nearby values within the error tolerance, that have fewer
|
|
1641
|
+
// bits set.
|
|
1642
|
+
//
|
|
1643
|
+
// The list of candidates has been pre-computed and sorted
|
|
1644
|
+
// in order of increasing numbers of bits set. This way, we
|
|
1645
|
+
// can stop searching as soon as we find a candidate that
|
|
1646
|
+
// is within the error tolerance.
|
|
1647
|
+
//
|
|
1648
|
+
|
|
1649
|
+
half
|
|
1650
|
+
DwaCompressor::LossyDctEncoderBase::quantize (half src, float errorTolerance)
|
|
1651
|
+
{
|
|
1652
|
+
half tmp;
|
|
1653
|
+
float srcFloat = (float)src;
|
|
1654
|
+
int numSetBits = countSetBits(src.bits());
|
|
1655
|
+
const unsigned short *closest = closestData + closestDataOffset[src.bits()];
|
|
1656
|
+
|
|
1657
|
+
for (int targetNumSetBits = numSetBits - 1;
|
|
1658
|
+
targetNumSetBits >= 0;
|
|
1659
|
+
--targetNumSetBits)
|
|
1660
|
+
{
|
|
1661
|
+
tmp.setBits (*closest);
|
|
1662
|
+
|
|
1663
|
+
if (fabs ((float)tmp - srcFloat) < errorTolerance)
|
|
1664
|
+
return tmp;
|
|
1665
|
+
|
|
1666
|
+
closest++;
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
return src;
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
|
|
1673
|
+
//
|
|
1674
|
+
// RLE the zig-zag of the AC components + copy over
|
|
1675
|
+
// into another tmp buffer
|
|
1676
|
+
//
|
|
1677
|
+
// Try to do a simple RLE scheme to reduce run's of 0's. This
|
|
1678
|
+
// differs from the jpeg EOB case, since EOB just indicates that
|
|
1679
|
+
// the rest of the block is zero. In our case, we have lots of
|
|
1680
|
+
// NaN symbols, which shouldn't be allowed to occur in DCT
|
|
1681
|
+
// coefficents - so we'll use them for encoding runs.
|
|
1682
|
+
//
|
|
1683
|
+
// If the high byte is 0xff, then we have a run of 0's, of length
|
|
1684
|
+
// given by the low byte. For example, 0xff03 would be a run
|
|
1685
|
+
// of 3 0's, starting at the current location.
|
|
1686
|
+
//
|
|
1687
|
+
// block is our block of 64 coefficients
|
|
1688
|
+
// acPtr a pointer to back the RLE'd values into.
|
|
1689
|
+
//
|
|
1690
|
+
// This will advance the counter, _numAcComp.
|
|
1691
|
+
//
|
|
1692
|
+
|
|
1693
|
+
void
|
|
1694
|
+
DwaCompressor::LossyDctEncoderBase::rleAc
|
|
1695
|
+
(half *block,
|
|
1696
|
+
unsigned short *&acPtr)
|
|
1697
|
+
{
|
|
1698
|
+
int dctComp = 1;
|
|
1699
|
+
unsigned short rleSymbol = 0x0;
|
|
1700
|
+
|
|
1701
|
+
while (dctComp < 64)
|
|
1702
|
+
{
|
|
1703
|
+
int runLen = 1;
|
|
1704
|
+
|
|
1705
|
+
//
|
|
1706
|
+
// If we don't have a 0, output verbatim
|
|
1707
|
+
//
|
|
1708
|
+
|
|
1709
|
+
if (block[dctComp].bits() != rleSymbol)
|
|
1710
|
+
{
|
|
1711
|
+
*acPtr++ = block[dctComp].bits();
|
|
1712
|
+
_numAcComp++;
|
|
1713
|
+
|
|
1714
|
+
dctComp += runLen;
|
|
1715
|
+
continue;
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
//
|
|
1719
|
+
// We're sitting on a 0, so see how big the run is.
|
|
1720
|
+
//
|
|
1721
|
+
|
|
1722
|
+
while ((dctComp+runLen < 64) &&
|
|
1723
|
+
(block[dctComp+runLen].bits() == rleSymbol))
|
|
1724
|
+
{
|
|
1725
|
+
runLen++;
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
//
|
|
1729
|
+
// If the run len is too small, just output verbatim
|
|
1730
|
+
// otherwise output our run token
|
|
1731
|
+
//
|
|
1732
|
+
// Originally, we wouldn't have a separate symbol for
|
|
1733
|
+
// "end of block". But in some experimentation, it looks
|
|
1734
|
+
// like using 0xff00 for "end of block" can save a bit
|
|
1735
|
+
// of space.
|
|
1736
|
+
//
|
|
1737
|
+
|
|
1738
|
+
if (runLen == 1)
|
|
1739
|
+
{
|
|
1740
|
+
runLen = 1;
|
|
1741
|
+
*acPtr++ = block[dctComp].bits();
|
|
1742
|
+
_numAcComp++;
|
|
1743
|
+
|
|
1744
|
+
//
|
|
1745
|
+
// Using 0xff00 for "end of block"
|
|
1746
|
+
//
|
|
1747
|
+
}
|
|
1748
|
+
else if (runLen + dctComp == 64)
|
|
1749
|
+
{
|
|
1750
|
+
//
|
|
1751
|
+
// Signal EOB
|
|
1752
|
+
//
|
|
1753
|
+
|
|
1754
|
+
*acPtr++ = 0xff00;
|
|
1755
|
+
_numAcComp++;
|
|
1756
|
+
}
|
|
1757
|
+
else
|
|
1758
|
+
{
|
|
1759
|
+
//
|
|
1760
|
+
// Signal normal run
|
|
1761
|
+
//
|
|
1762
|
+
|
|
1763
|
+
*acPtr++ = 0xff00 | runLen;
|
|
1764
|
+
_numAcComp++;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
//
|
|
1768
|
+
// Advance by runLen
|
|
1769
|
+
//
|
|
1770
|
+
|
|
1771
|
+
dctComp += runLen;
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
// ==============================================================
|
|
1777
|
+
//
|
|
1778
|
+
// DwaCompressor
|
|
1779
|
+
//
|
|
1780
|
+
// --------------------------------------------------------------
|
|
1781
|
+
|
|
1782
|
+
//
|
|
1783
|
+
// DwaCompressor()
|
|
1784
|
+
//
|
|
1785
|
+
|
|
1786
|
+
DwaCompressor::DwaCompressor
|
|
1787
|
+
(const Header &hdr,
|
|
1788
|
+
int maxScanLineSize,
|
|
1789
|
+
int numScanLines,
|
|
1790
|
+
AcCompression acCompression)
|
|
1791
|
+
:
|
|
1792
|
+
Compressor(hdr),
|
|
1793
|
+
_acCompression(acCompression),
|
|
1794
|
+
_maxScanLineSize(maxScanLineSize),
|
|
1795
|
+
_numScanLines(numScanLines),
|
|
1796
|
+
_channels(hdr.channels()),
|
|
1797
|
+
_packedAcBuffer(0),
|
|
1798
|
+
_packedAcBufferSize(0),
|
|
1799
|
+
_packedDcBuffer(0),
|
|
1800
|
+
_packedDcBufferSize(0),
|
|
1801
|
+
_rleBuffer(0),
|
|
1802
|
+
_rleBufferSize(0),
|
|
1803
|
+
_outBuffer(0),
|
|
1804
|
+
_outBufferSize(0),
|
|
1805
|
+
_zip(0),
|
|
1806
|
+
_dwaCompressionLevel(45.0)
|
|
1807
|
+
{
|
|
1808
|
+
_min[0] = hdr.dataWindow().min.x;
|
|
1809
|
+
_min[1] = hdr.dataWindow().min.y;
|
|
1810
|
+
_max[0] = hdr.dataWindow().max.x;
|
|
1811
|
+
_max[1] = hdr.dataWindow().max.y;
|
|
1812
|
+
|
|
1813
|
+
for (int i=0; i < NUM_COMPRESSOR_SCHEMES; ++i)
|
|
1814
|
+
{
|
|
1815
|
+
_planarUncBuffer[i] = 0;
|
|
1816
|
+
_planarUncBufferSize[i] = 0;
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
//
|
|
1820
|
+
// Check the header for a quality attribute
|
|
1821
|
+
//
|
|
1822
|
+
|
|
1823
|
+
if (hasDwaCompressionLevel (hdr))
|
|
1824
|
+
_dwaCompressionLevel = dwaCompressionLevel (hdr);
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
DwaCompressor::~DwaCompressor()
|
|
1829
|
+
{
|
|
1830
|
+
delete[] _packedAcBuffer;
|
|
1831
|
+
delete[] _packedDcBuffer;
|
|
1832
|
+
delete[] _rleBuffer;
|
|
1833
|
+
delete[] _outBuffer;
|
|
1834
|
+
delete _zip;
|
|
1835
|
+
|
|
1836
|
+
for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
|
|
1837
|
+
delete[] _planarUncBuffer[i];
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
|
|
1841
|
+
int
|
|
1842
|
+
DwaCompressor::numScanLines() const
|
|
1843
|
+
{
|
|
1844
|
+
return _numScanLines;
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
|
|
1848
|
+
Imf::Compressor::Format
|
|
1849
|
+
DwaCompressor::format() const
|
|
1850
|
+
{
|
|
1851
|
+
if (GLOBAL_SYSTEM_LITTLE_ENDIAN)
|
|
1852
|
+
return NATIVE;
|
|
1853
|
+
else
|
|
1854
|
+
return XDR;
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
int
|
|
1859
|
+
DwaCompressor::compress
|
|
1860
|
+
(const char *inPtr,
|
|
1861
|
+
int inSize,
|
|
1862
|
+
int minY,
|
|
1863
|
+
const char *&outPtr)
|
|
1864
|
+
{
|
|
1865
|
+
return compress
|
|
1866
|
+
(inPtr,
|
|
1867
|
+
inSize,
|
|
1868
|
+
Imath::Box2i (Imath::V2i (_min[0], minY),
|
|
1869
|
+
Imath::V2i (_max[0], minY + numScanLines() - 1)),
|
|
1870
|
+
outPtr);
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
|
|
1874
|
+
int
|
|
1875
|
+
DwaCompressor::compressTile
|
|
1876
|
+
(const char *inPtr,
|
|
1877
|
+
int inSize,
|
|
1878
|
+
Imath::Box2i range,
|
|
1879
|
+
const char *&outPtr)
|
|
1880
|
+
{
|
|
1881
|
+
return compress (inPtr, inSize, range, outPtr);
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
|
|
1885
|
+
int
|
|
1886
|
+
DwaCompressor::compress
|
|
1887
|
+
(const char *inPtr,
|
|
1888
|
+
int inSize,
|
|
1889
|
+
Imath::Box2i range,
|
|
1890
|
+
const char *&outPtr)
|
|
1891
|
+
{
|
|
1892
|
+
const char *inDataPtr = inPtr;
|
|
1893
|
+
char *packedAcEnd = 0;
|
|
1894
|
+
char *packedDcEnd = 0;
|
|
1895
|
+
int fileVersion = 2; // Starting with 2, we write the channel
|
|
1896
|
+
// classification rules into the file
|
|
1897
|
+
|
|
1898
|
+
if (fileVersion < 2)
|
|
1899
|
+
initializeLegacyChannelRules();
|
|
1900
|
+
else
|
|
1901
|
+
initializeDefaultChannelRules();
|
|
1902
|
+
|
|
1903
|
+
size_t outBufferSize = 0;
|
|
1904
|
+
initializeBuffers(outBufferSize);
|
|
1905
|
+
|
|
1906
|
+
unsigned short channelRuleSize = 0;
|
|
1907
|
+
std::vector<Classifier> channelRules;
|
|
1908
|
+
if (fileVersion >= 2)
|
|
1909
|
+
{
|
|
1910
|
+
relevantChannelRules(channelRules);
|
|
1911
|
+
|
|
1912
|
+
channelRuleSize = Xdr::size<unsigned short>();
|
|
1913
|
+
for (size_t i = 0; i < channelRules.size(); ++i)
|
|
1914
|
+
channelRuleSize += channelRules[i].size();
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
//
|
|
1918
|
+
// Remember to allocate _outBuffer, if we haven't done so already.
|
|
1919
|
+
//
|
|
1920
|
+
|
|
1921
|
+
outBufferSize += channelRuleSize;
|
|
1922
|
+
if (outBufferSize > _outBufferSize)
|
|
1923
|
+
{
|
|
1924
|
+
_outBufferSize = outBufferSize;
|
|
1925
|
+
if (_outBuffer == 0)
|
|
1926
|
+
delete[] _outBuffer;
|
|
1927
|
+
_outBuffer = new char[outBufferSize];
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
char *outDataPtr = &_outBuffer[NUM_SIZES_SINGLE * sizeof(Imf::Int64) +
|
|
1931
|
+
channelRuleSize];
|
|
1932
|
+
|
|
1933
|
+
//
|
|
1934
|
+
// We might not be dealing with any color data, in which
|
|
1935
|
+
// case the AC buffer size will be 0, and deferencing
|
|
1936
|
+
// a vector will not be a good thing to do.
|
|
1937
|
+
//
|
|
1938
|
+
|
|
1939
|
+
if (_packedAcBuffer)
|
|
1940
|
+
packedAcEnd = _packedAcBuffer;
|
|
1941
|
+
|
|
1942
|
+
if (_packedDcBuffer)
|
|
1943
|
+
packedDcEnd = _packedDcBuffer;
|
|
1944
|
+
|
|
1945
|
+
#define OBIDX(x) (Int64 *)&_outBuffer[x * sizeof (Int64)]
|
|
1946
|
+
|
|
1947
|
+
Int64 *version = OBIDX (VERSION);
|
|
1948
|
+
Int64 *unknownUncompressedSize = OBIDX (UNKNOWN_UNCOMPRESSED_SIZE);
|
|
1949
|
+
Int64 *unknownCompressedSize = OBIDX (UNKNOWN_COMPRESSED_SIZE);
|
|
1950
|
+
Int64 *acCompressedSize = OBIDX (AC_COMPRESSED_SIZE);
|
|
1951
|
+
Int64 *dcCompressedSize = OBIDX (DC_COMPRESSED_SIZE);
|
|
1952
|
+
Int64 *rleCompressedSize = OBIDX (RLE_COMPRESSED_SIZE);
|
|
1953
|
+
Int64 *rleUncompressedSize = OBIDX (RLE_UNCOMPRESSED_SIZE);
|
|
1954
|
+
Int64 *rleRawSize = OBIDX (RLE_RAW_SIZE);
|
|
1955
|
+
|
|
1956
|
+
Int64 *totalAcUncompressedCount = OBIDX (AC_UNCOMPRESSED_COUNT);
|
|
1957
|
+
Int64 *totalDcUncompressedCount = OBIDX (DC_UNCOMPRESSED_COUNT);
|
|
1958
|
+
|
|
1959
|
+
Int64 *acCompression = OBIDX (AC_COMPRESSION);
|
|
1960
|
+
|
|
1961
|
+
int minX = range.min.x;
|
|
1962
|
+
int maxX = std::min(range.max.x, _max[0]);
|
|
1963
|
+
int minY = range.min.y;
|
|
1964
|
+
int maxY = std::min(range.max.y, _max[1]);
|
|
1965
|
+
|
|
1966
|
+
//
|
|
1967
|
+
// Zero all the numbers in the chunk header
|
|
1968
|
+
//
|
|
1969
|
+
|
|
1970
|
+
memset (_outBuffer, 0, NUM_SIZES_SINGLE * sizeof (Int64));
|
|
1971
|
+
|
|
1972
|
+
//
|
|
1973
|
+
// Setup the AC compression strategy and the version in the data block,
|
|
1974
|
+
// then write the relevant channel classification rules if needed
|
|
1975
|
+
//
|
|
1976
|
+
*version = fileVersion;
|
|
1977
|
+
*acCompression = _acCompression;
|
|
1978
|
+
|
|
1979
|
+
setupChannelData (minX, minY, maxX, maxY);
|
|
1980
|
+
|
|
1981
|
+
if (fileVersion >= 2)
|
|
1982
|
+
{
|
|
1983
|
+
char *writePtr = &_outBuffer[NUM_SIZES_SINGLE * sizeof(Imf::Int64)];
|
|
1984
|
+
Xdr::write<CharPtrIO> (writePtr, channelRuleSize);
|
|
1985
|
+
|
|
1986
|
+
for (size_t i = 0; i < channelRules.size(); ++i)
|
|
1987
|
+
channelRules[i].write(writePtr);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
//
|
|
1991
|
+
// Determine the start of each row in the input buffer
|
|
1992
|
+
// Channels are interleaved by scanline
|
|
1993
|
+
//
|
|
1994
|
+
|
|
1995
|
+
std::vector<bool> encodedChannels (_channelData.size());
|
|
1996
|
+
std::vector< std::vector<const char *> > rowPtrs (_channelData.size());
|
|
1997
|
+
|
|
1998
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
1999
|
+
encodedChannels[chan] = false;
|
|
2000
|
+
|
|
2001
|
+
inDataPtr = inPtr;
|
|
2002
|
+
|
|
2003
|
+
for (int y = minY; y <= maxY; ++y)
|
|
2004
|
+
{
|
|
2005
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
2006
|
+
{
|
|
2007
|
+
|
|
2008
|
+
ChannelData *cd = &_channelData[chan];
|
|
2009
|
+
|
|
2010
|
+
if (Imath::modp(y, cd->ySampling) != 0)
|
|
2011
|
+
continue;
|
|
2012
|
+
|
|
2013
|
+
rowPtrs[chan].push_back(inDataPtr);
|
|
2014
|
+
inDataPtr += cd->width * Imf::pixelTypeSize(cd->type);
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
inDataPtr = inPtr;
|
|
2019
|
+
|
|
2020
|
+
//
|
|
2021
|
+
// Make a pass over all our CSC sets and try to encode them first
|
|
2022
|
+
//
|
|
2023
|
+
|
|
2024
|
+
for (unsigned int csc = 0; csc < _cscSets.size(); ++csc)
|
|
2025
|
+
{
|
|
2026
|
+
|
|
2027
|
+
LossyDctEncoderCsc encoder
|
|
2028
|
+
(_dwaCompressionLevel / 100000.f,
|
|
2029
|
+
rowPtrs[_cscSets[csc].idx[0]],
|
|
2030
|
+
rowPtrs[_cscSets[csc].idx[1]],
|
|
2031
|
+
rowPtrs[_cscSets[csc].idx[2]],
|
|
2032
|
+
packedAcEnd,
|
|
2033
|
+
packedDcEnd,
|
|
2034
|
+
dwaCompressorToNonlinear,
|
|
2035
|
+
_channelData[_cscSets[csc].idx[0]].width,
|
|
2036
|
+
_channelData[_cscSets[csc].idx[0]].height,
|
|
2037
|
+
_channelData[_cscSets[csc].idx[0]].type,
|
|
2038
|
+
_channelData[_cscSets[csc].idx[1]].type,
|
|
2039
|
+
_channelData[_cscSets[csc].idx[2]].type);
|
|
2040
|
+
|
|
2041
|
+
encoder.execute();
|
|
2042
|
+
|
|
2043
|
+
*totalAcUncompressedCount += encoder.numAcValuesEncoded();
|
|
2044
|
+
*totalDcUncompressedCount += encoder.numDcValuesEncoded();
|
|
2045
|
+
|
|
2046
|
+
packedAcEnd += encoder.numAcValuesEncoded() * sizeof(unsigned short);
|
|
2047
|
+
packedDcEnd += encoder.numDcValuesEncoded() * sizeof(unsigned short);
|
|
2048
|
+
|
|
2049
|
+
encodedChannels[_cscSets[csc].idx[0]] = true;
|
|
2050
|
+
encodedChannels[_cscSets[csc].idx[1]] = true;
|
|
2051
|
+
encodedChannels[_cscSets[csc].idx[2]] = true;
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
2055
|
+
{
|
|
2056
|
+
ChannelData *cd = &_channelData[chan];
|
|
2057
|
+
|
|
2058
|
+
if (encodedChannels[chan])
|
|
2059
|
+
continue;
|
|
2060
|
+
|
|
2061
|
+
switch (cd->compression)
|
|
2062
|
+
{
|
|
2063
|
+
case LOSSY_DCT:
|
|
2064
|
+
|
|
2065
|
+
//
|
|
2066
|
+
// For LOSSY_DCT, treat this just like the CSC'd case,
|
|
2067
|
+
// but only operate on one channel
|
|
2068
|
+
//
|
|
2069
|
+
|
|
2070
|
+
{
|
|
2071
|
+
const unsigned short *nonlinearLut = 0;
|
|
2072
|
+
|
|
2073
|
+
if (!cd->pLinear)
|
|
2074
|
+
nonlinearLut = dwaCompressorToNonlinear;
|
|
2075
|
+
|
|
2076
|
+
LossyDctEncoder encoder
|
|
2077
|
+
(_dwaCompressionLevel / 100000.f,
|
|
2078
|
+
rowPtrs[chan],
|
|
2079
|
+
packedAcEnd,
|
|
2080
|
+
packedDcEnd,
|
|
2081
|
+
nonlinearLut,
|
|
2082
|
+
cd->width,
|
|
2083
|
+
cd->height,
|
|
2084
|
+
cd->type);
|
|
2085
|
+
|
|
2086
|
+
encoder.execute();
|
|
2087
|
+
|
|
2088
|
+
*totalAcUncompressedCount += encoder.numAcValuesEncoded();
|
|
2089
|
+
*totalDcUncompressedCount += encoder.numDcValuesEncoded();
|
|
2090
|
+
|
|
2091
|
+
packedAcEnd +=
|
|
2092
|
+
encoder.numAcValuesEncoded() * sizeof (unsigned short);
|
|
2093
|
+
|
|
2094
|
+
packedDcEnd +=
|
|
2095
|
+
encoder.numDcValuesEncoded() * sizeof (unsigned short);
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
break;
|
|
2099
|
+
|
|
2100
|
+
case RLE:
|
|
2101
|
+
|
|
2102
|
+
//
|
|
2103
|
+
// For RLE, bash the bytes up so that the first bytes of each
|
|
2104
|
+
// pixel are contingous, as are the second bytes, and so on.
|
|
2105
|
+
//
|
|
2106
|
+
|
|
2107
|
+
for (unsigned int y = 0; y < rowPtrs[chan].size(); ++y)
|
|
2108
|
+
{
|
|
2109
|
+
const char *row = rowPtrs[chan][y];
|
|
2110
|
+
|
|
2111
|
+
for (int x = 0; x < cd->width; ++x)
|
|
2112
|
+
{
|
|
2113
|
+
for (int byte = 0;
|
|
2114
|
+
byte < Imf::pixelTypeSize (cd->type);
|
|
2115
|
+
++byte)
|
|
2116
|
+
{
|
|
2117
|
+
|
|
2118
|
+
*cd->planarUncRleEnd[byte]++ = *row++;
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
*rleRawSize += cd->width * Imf::pixelTypeSize(cd->type);
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
break;
|
|
2126
|
+
|
|
2127
|
+
case UNKNOWN:
|
|
2128
|
+
|
|
2129
|
+
//
|
|
2130
|
+
// Otherwise, just copy data over verbatim
|
|
2131
|
+
//
|
|
2132
|
+
|
|
2133
|
+
{
|
|
2134
|
+
int scanlineSize = cd->width * Imf::pixelTypeSize(cd->type);
|
|
2135
|
+
|
|
2136
|
+
for (unsigned int y = 0; y < rowPtrs[chan].size(); ++y)
|
|
2137
|
+
{
|
|
2138
|
+
memcpy (cd->planarUncBufferEnd,
|
|
2139
|
+
rowPtrs[chan][y],
|
|
2140
|
+
scanlineSize);
|
|
2141
|
+
|
|
2142
|
+
cd->planarUncBufferEnd += scanlineSize;
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
*unknownUncompressedSize += cd->planarUncSize;
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
break;
|
|
2149
|
+
|
|
2150
|
+
default:
|
|
2151
|
+
|
|
2152
|
+
assert (false);
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
encodedChannels[chan] = true;
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
//
|
|
2159
|
+
// Pack the Unknown data into the output buffer first. Instead of
|
|
2160
|
+
// just copying it uncompressed, try zlib compression at least.
|
|
2161
|
+
//
|
|
2162
|
+
|
|
2163
|
+
if (*unknownUncompressedSize > 0)
|
|
2164
|
+
{
|
|
2165
|
+
uLongf inSize = (uLongf)(*unknownUncompressedSize);
|
|
2166
|
+
uLongf outSize = (uLongf)(ceil ((float)inSize * 1.01f) + 100);
|
|
2167
|
+
|
|
2168
|
+
if (Z_OK != ::compress2 ((Bytef *)outDataPtr,
|
|
2169
|
+
&outSize,
|
|
2170
|
+
(const Bytef *)_planarUncBuffer[UNKNOWN],
|
|
2171
|
+
inSize,
|
|
2172
|
+
9))
|
|
2173
|
+
{
|
|
2174
|
+
throw Iex::BaseExc ("Data compression (zlib) failed.");
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
outDataPtr += outSize;
|
|
2178
|
+
*unknownCompressedSize = outSize;
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
//
|
|
2182
|
+
// Now, pack all the Lossy DCT coefficients into our output
|
|
2183
|
+
// buffer, with Huffman encoding.
|
|
2184
|
+
//
|
|
2185
|
+
// Also, record the compressed size and the number of
|
|
2186
|
+
// uncompressed componentns we have.
|
|
2187
|
+
//
|
|
2188
|
+
|
|
2189
|
+
if (*totalAcUncompressedCount > 0)
|
|
2190
|
+
{
|
|
2191
|
+
switch (_acCompression)
|
|
2192
|
+
{
|
|
2193
|
+
case STATIC_HUFFMAN:
|
|
2194
|
+
|
|
2195
|
+
*acCompressedSize = (int)
|
|
2196
|
+
hufCompress((unsigned short *)_packedAcBuffer,
|
|
2197
|
+
(int)*totalAcUncompressedCount,
|
|
2198
|
+
outDataPtr);
|
|
2199
|
+
break;
|
|
2200
|
+
|
|
2201
|
+
case DEFLATE:
|
|
2202
|
+
|
|
2203
|
+
{
|
|
2204
|
+
uLongf destLen = (uLongf)
|
|
2205
|
+
(2 * (*totalAcUncompressedCount) * sizeof (unsigned short));
|
|
2206
|
+
|
|
2207
|
+
if (Z_OK != ::compress2
|
|
2208
|
+
((Bytef *)outDataPtr,
|
|
2209
|
+
&destLen,
|
|
2210
|
+
(Bytef *)_packedAcBuffer,
|
|
2211
|
+
(uLong)(*totalAcUncompressedCount
|
|
2212
|
+
* sizeof (unsigned short)),
|
|
2213
|
+
9))
|
|
2214
|
+
{
|
|
2215
|
+
throw Iex::InputExc ("Data compression (zlib) failed.");
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
*acCompressedSize = destLen;
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
break;
|
|
2222
|
+
|
|
2223
|
+
default:
|
|
2224
|
+
|
|
2225
|
+
assert (false);
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
outDataPtr += *acCompressedSize;
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
//
|
|
2232
|
+
// Handle the DC components separately
|
|
2233
|
+
//
|
|
2234
|
+
|
|
2235
|
+
if (*totalDcUncompressedCount > 0)
|
|
2236
|
+
{
|
|
2237
|
+
*dcCompressedSize = _zip->compress
|
|
2238
|
+
(_packedDcBuffer,
|
|
2239
|
+
(int)(*totalDcUncompressedCount) * sizeof (unsigned short),
|
|
2240
|
+
outDataPtr);
|
|
2241
|
+
|
|
2242
|
+
outDataPtr += *dcCompressedSize;
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
//
|
|
2246
|
+
// If we have RLE data, first RLE encode it and set the uncompressed
|
|
2247
|
+
// size. Then, deflate the results and set the compressed size.
|
|
2248
|
+
//
|
|
2249
|
+
|
|
2250
|
+
if (*rleRawSize > 0)
|
|
2251
|
+
{
|
|
2252
|
+
*rleUncompressedSize = rleCompress
|
|
2253
|
+
((int)(*rleRawSize),
|
|
2254
|
+
_planarUncBuffer[RLE],
|
|
2255
|
+
(signed char *)_rleBuffer);
|
|
2256
|
+
|
|
2257
|
+
uLongf dstLen =
|
|
2258
|
+
(uLongf)ceil (1.01f * (float) * rleUncompressedSize) + 24;
|
|
2259
|
+
|
|
2260
|
+
if (Z_OK != ::compress2
|
|
2261
|
+
((Bytef *)outDataPtr,
|
|
2262
|
+
&dstLen,
|
|
2263
|
+
(Bytef *)_rleBuffer,
|
|
2264
|
+
(uLong)(*rleUncompressedSize),
|
|
2265
|
+
9))
|
|
2266
|
+
{
|
|
2267
|
+
throw Iex::BaseExc ("Error compressing RLE'd data.");
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
*rleCompressedSize = dstLen;
|
|
2271
|
+
outDataPtr += *rleCompressedSize;
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
//
|
|
2275
|
+
// Flip the counters to XDR format
|
|
2276
|
+
//
|
|
2277
|
+
|
|
2278
|
+
for (int i = 0; i < NUM_SIZES_SINGLE; ++i)
|
|
2279
|
+
{
|
|
2280
|
+
Int64 src = *(((Int64 *)_outBuffer) + i);
|
|
2281
|
+
char *dst = (char *)(((Int64 *)_outBuffer) + i);
|
|
2282
|
+
|
|
2283
|
+
Xdr::write<CharPtrIO> (dst, src);
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
//
|
|
2287
|
+
// We're done - compute the number of bytes we packed
|
|
2288
|
+
//
|
|
2289
|
+
|
|
2290
|
+
outPtr = _outBuffer;
|
|
2291
|
+
|
|
2292
|
+
return static_cast<int>(outDataPtr - _outBuffer + 1);
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
|
|
2296
|
+
int
|
|
2297
|
+
DwaCompressor::uncompress
|
|
2298
|
+
(const char *inPtr,
|
|
2299
|
+
int inSize,
|
|
2300
|
+
int minY,
|
|
2301
|
+
const char *&outPtr)
|
|
2302
|
+
{
|
|
2303
|
+
return uncompress (inPtr,
|
|
2304
|
+
inSize,
|
|
2305
|
+
Imath::Box2i (Imath::V2i (_min[0], minY),
|
|
2306
|
+
Imath::V2i (_max[0], minY + numScanLines() - 1)),
|
|
2307
|
+
outPtr);
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
|
|
2311
|
+
int
|
|
2312
|
+
DwaCompressor::uncompressTile
|
|
2313
|
+
(const char *inPtr,
|
|
2314
|
+
int inSize,
|
|
2315
|
+
Imath::Box2i range,
|
|
2316
|
+
const char *&outPtr)
|
|
2317
|
+
{
|
|
2318
|
+
return uncompress (inPtr, inSize, range, outPtr);
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
|
|
2322
|
+
int
|
|
2323
|
+
DwaCompressor::uncompress
|
|
2324
|
+
(const char *inPtr,
|
|
2325
|
+
int inSize,
|
|
2326
|
+
Imath::Box2i range,
|
|
2327
|
+
const char *&outPtr)
|
|
2328
|
+
{
|
|
2329
|
+
int minX = range.min.x;
|
|
2330
|
+
int maxX = std::min (range.max.x, _max[0]);
|
|
2331
|
+
int minY = range.min.y;
|
|
2332
|
+
int maxY = std::min (range.max.y, _max[1]);
|
|
2333
|
+
|
|
2334
|
+
int headerSize = NUM_SIZES_SINGLE*sizeof(Int64);
|
|
2335
|
+
if (inSize < headerSize)
|
|
2336
|
+
{
|
|
2337
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2338
|
+
"(truncated header).");
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
//
|
|
2342
|
+
// Flip the counters from XDR to NATIVE
|
|
2343
|
+
//
|
|
2344
|
+
|
|
2345
|
+
for (int i = 0; i < NUM_SIZES_SINGLE; ++i)
|
|
2346
|
+
{
|
|
2347
|
+
Int64 *dst = (((Int64 *)inPtr) + i);
|
|
2348
|
+
const char *src = (char *)(((Int64 *)inPtr) + i);
|
|
2349
|
+
|
|
2350
|
+
Xdr::read<CharPtrIO> (src, *dst);
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
//
|
|
2354
|
+
// Unwind all the counter info
|
|
2355
|
+
//
|
|
2356
|
+
|
|
2357
|
+
const Int64 *inPtr64 = (const Int64*) inPtr;
|
|
2358
|
+
|
|
2359
|
+
Int64 version = *(inPtr64 + VERSION);
|
|
2360
|
+
Int64 unknownUncompressedSize = *(inPtr64 + UNKNOWN_UNCOMPRESSED_SIZE);
|
|
2361
|
+
Int64 unknownCompressedSize = *(inPtr64 + UNKNOWN_COMPRESSED_SIZE);
|
|
2362
|
+
Int64 acCompressedSize = *(inPtr64 + AC_COMPRESSED_SIZE);
|
|
2363
|
+
Int64 dcCompressedSize = *(inPtr64 + DC_COMPRESSED_SIZE);
|
|
2364
|
+
Int64 rleCompressedSize = *(inPtr64 + RLE_COMPRESSED_SIZE);
|
|
2365
|
+
Int64 rleUncompressedSize = *(inPtr64 + RLE_UNCOMPRESSED_SIZE);
|
|
2366
|
+
Int64 rleRawSize = *(inPtr64 + RLE_RAW_SIZE);
|
|
2367
|
+
|
|
2368
|
+
Int64 totalAcUncompressedCount = *(inPtr64 + AC_UNCOMPRESSED_COUNT);
|
|
2369
|
+
Int64 totalDcUncompressedCount = *(inPtr64 + DC_UNCOMPRESSED_COUNT);
|
|
2370
|
+
|
|
2371
|
+
Int64 acCompression = *(inPtr64 + AC_COMPRESSION);
|
|
2372
|
+
|
|
2373
|
+
Int64 compressedSize = unknownCompressedSize +
|
|
2374
|
+
acCompressedSize +
|
|
2375
|
+
dcCompressedSize +
|
|
2376
|
+
rleCompressedSize;
|
|
2377
|
+
|
|
2378
|
+
const char *dataPtr = inPtr + NUM_SIZES_SINGLE * sizeof(Int64);
|
|
2379
|
+
|
|
2380
|
+
if (inSize < headerSize + compressedSize)
|
|
2381
|
+
{
|
|
2382
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2383
|
+
"(truncated file).");
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
if (unknownUncompressedSize < 0 ||
|
|
2387
|
+
unknownCompressedSize < 0 ||
|
|
2388
|
+
acCompressedSize < 0 ||
|
|
2389
|
+
dcCompressedSize < 0 ||
|
|
2390
|
+
rleCompressedSize < 0 ||
|
|
2391
|
+
rleUncompressedSize < 0 ||
|
|
2392
|
+
rleRawSize < 0 ||
|
|
2393
|
+
totalAcUncompressedCount < 0 ||
|
|
2394
|
+
totalDcUncompressedCount < 0)
|
|
2395
|
+
{
|
|
2396
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2397
|
+
" (corrupt header).");
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
if (version < 2)
|
|
2401
|
+
initializeLegacyChannelRules();
|
|
2402
|
+
else
|
|
2403
|
+
{
|
|
2404
|
+
unsigned short ruleSize = 0;
|
|
2405
|
+
Xdr::read<CharPtrIO>(dataPtr, ruleSize);
|
|
2406
|
+
|
|
2407
|
+
if (ruleSize < 0)
|
|
2408
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2409
|
+
" (corrupt header file).");
|
|
2410
|
+
|
|
2411
|
+
headerSize += ruleSize;
|
|
2412
|
+
if (inSize < headerSize + compressedSize)
|
|
2413
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2414
|
+
" (truncated file).");
|
|
2415
|
+
|
|
2416
|
+
_channelRules.clear();
|
|
2417
|
+
ruleSize -= Xdr::size<unsigned short> ();
|
|
2418
|
+
while (ruleSize > 0)
|
|
2419
|
+
{
|
|
2420
|
+
Classifier rule(dataPtr, ruleSize);
|
|
2421
|
+
|
|
2422
|
+
_channelRules.push_back(rule);
|
|
2423
|
+
ruleSize -= rule.size();
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
|
|
2428
|
+
size_t outBufferSize = 0;
|
|
2429
|
+
initializeBuffers(outBufferSize);
|
|
2430
|
+
|
|
2431
|
+
//
|
|
2432
|
+
// Allocate _outBuffer, if we haven't done so already
|
|
2433
|
+
//
|
|
2434
|
+
|
|
2435
|
+
if (_maxScanLineSize * numScanLines() > _outBufferSize)
|
|
2436
|
+
{
|
|
2437
|
+
_outBufferSize = _maxScanLineSize * numScanLines();
|
|
2438
|
+
if (_outBuffer != 0)
|
|
2439
|
+
delete[] _outBuffer;
|
|
2440
|
+
_outBuffer = new char[_maxScanLineSize * numScanLines()];
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
|
|
2444
|
+
char *outBufferEnd = _outBuffer;
|
|
2445
|
+
|
|
2446
|
+
|
|
2447
|
+
//
|
|
2448
|
+
// Find the start of the RLE packed AC components and
|
|
2449
|
+
// the DC components for each channel. This will be handy
|
|
2450
|
+
// if you want to decode the channels in parallel later on.
|
|
2451
|
+
//
|
|
2452
|
+
|
|
2453
|
+
char *packedAcBufferEnd = 0;
|
|
2454
|
+
|
|
2455
|
+
if (_packedAcBuffer)
|
|
2456
|
+
packedAcBufferEnd = _packedAcBuffer;
|
|
2457
|
+
|
|
2458
|
+
char *packedDcBufferEnd = 0;
|
|
2459
|
+
|
|
2460
|
+
if (_packedDcBuffer)
|
|
2461
|
+
packedDcBufferEnd = _packedDcBuffer;
|
|
2462
|
+
|
|
2463
|
+
//
|
|
2464
|
+
// UNKNOWN data is packed first, followed by the
|
|
2465
|
+
// Huffman-compressed AC, then the DC values,
|
|
2466
|
+
// and then the zlib compressed RLE data.
|
|
2467
|
+
//
|
|
2468
|
+
|
|
2469
|
+
const char *compressedUnknownBuf = dataPtr;
|
|
2470
|
+
|
|
2471
|
+
const char *compressedAcBuf = compressedUnknownBuf +
|
|
2472
|
+
static_cast<ptrdiff_t>(unknownCompressedSize);
|
|
2473
|
+
const char *compressedDcBuf = compressedAcBuf +
|
|
2474
|
+
static_cast<ptrdiff_t>(acCompressedSize);
|
|
2475
|
+
const char *compressedRleBuf = compressedDcBuf +
|
|
2476
|
+
static_cast<ptrdiff_t>(dcCompressedSize);
|
|
2477
|
+
|
|
2478
|
+
//
|
|
2479
|
+
// Sanity check that the version is something we expect. Right now,
|
|
2480
|
+
// we can decode version 0, 1, and 2. v1 adds 'end of block' symbols
|
|
2481
|
+
// to the AC RLE. v2 adds channel classification rules at the
|
|
2482
|
+
// start of the data block.
|
|
2483
|
+
//
|
|
2484
|
+
|
|
2485
|
+
if ((version < 0) || (version > 2))
|
|
2486
|
+
throw Iex::InputExc ("Invalid version of compressed data block");
|
|
2487
|
+
|
|
2488
|
+
setupChannelData(minX, minY, maxX, maxY);
|
|
2489
|
+
|
|
2490
|
+
//
|
|
2491
|
+
// Uncompress the UNKNOWN data into _planarUncBuffer[UNKNOWN]
|
|
2492
|
+
//
|
|
2493
|
+
|
|
2494
|
+
if (unknownCompressedSize > 0)
|
|
2495
|
+
{
|
|
2496
|
+
uLongf outSize = static_cast<uLongf>(
|
|
2497
|
+
ceil( (float)unknownUncompressedSize * 1.01) + 100);
|
|
2498
|
+
|
|
2499
|
+
if (unknownUncompressedSize < 0 ||
|
|
2500
|
+
outSize > _planarUncBufferSize[UNKNOWN])
|
|
2501
|
+
{
|
|
2502
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2503
|
+
"(corrupt header).");
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
if (Z_OK != ::uncompress
|
|
2507
|
+
((Bytef *)_planarUncBuffer[UNKNOWN],
|
|
2508
|
+
&outSize,
|
|
2509
|
+
(Bytef *)compressedUnknownBuf,
|
|
2510
|
+
(uLong)unknownCompressedSize))
|
|
2511
|
+
{
|
|
2512
|
+
throw Iex::BaseExc("Error uncompressing UNKNOWN data.");
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
//
|
|
2517
|
+
// Uncompress the AC data into _packedAcBuffer
|
|
2518
|
+
//
|
|
2519
|
+
|
|
2520
|
+
if (acCompressedSize > 0)
|
|
2521
|
+
{
|
|
2522
|
+
if (totalAcUncompressedCount*sizeof(unsigned short) > _packedAcBufferSize)
|
|
2523
|
+
{
|
|
2524
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2525
|
+
"(corrupt header).");
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
//
|
|
2529
|
+
// Don't trust the user to get it right, look in the file.
|
|
2530
|
+
//
|
|
2531
|
+
|
|
2532
|
+
switch (acCompression)
|
|
2533
|
+
{
|
|
2534
|
+
case STATIC_HUFFMAN:
|
|
2535
|
+
|
|
2536
|
+
hufUncompress
|
|
2537
|
+
(compressedAcBuf,
|
|
2538
|
+
(int)acCompressedSize,
|
|
2539
|
+
(unsigned short *)_packedAcBuffer,
|
|
2540
|
+
(int)totalAcUncompressedCount);
|
|
2541
|
+
|
|
2542
|
+
break;
|
|
2543
|
+
|
|
2544
|
+
case DEFLATE:
|
|
2545
|
+
{
|
|
2546
|
+
uLongf destLen =
|
|
2547
|
+
(int)(totalAcUncompressedCount) * sizeof (unsigned short);
|
|
2548
|
+
|
|
2549
|
+
if (Z_OK != ::uncompress
|
|
2550
|
+
((Bytef *)_packedAcBuffer,
|
|
2551
|
+
&destLen,
|
|
2552
|
+
(Bytef *)compressedAcBuf,
|
|
2553
|
+
(uLong)acCompressedSize))
|
|
2554
|
+
{
|
|
2555
|
+
throw Iex::InputExc ("Data decompression (zlib) failed.");
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
if (totalAcUncompressedCount * sizeof (unsigned short) !=
|
|
2559
|
+
destLen)
|
|
2560
|
+
{
|
|
2561
|
+
throw Iex::InputExc ("AC data corrupt.");
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
break;
|
|
2565
|
+
|
|
2566
|
+
default:
|
|
2567
|
+
|
|
2568
|
+
throw Iex::NoImplExc ("Unknown AC Compression");
|
|
2569
|
+
break;
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
|
|
2573
|
+
//
|
|
2574
|
+
// Uncompress the DC data into _packedDcBuffer
|
|
2575
|
+
//
|
|
2576
|
+
|
|
2577
|
+
if (dcCompressedSize > 0)
|
|
2578
|
+
{
|
|
2579
|
+
if (totalDcUncompressedCount*sizeof(unsigned short) > _packedDcBufferSize)
|
|
2580
|
+
{
|
|
2581
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2582
|
+
"(corrupt header).");
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
if (_zip->uncompress
|
|
2586
|
+
(compressedDcBuf, (int)dcCompressedSize, _packedDcBuffer)
|
|
2587
|
+
!= (int)totalDcUncompressedCount * sizeof (unsigned short))
|
|
2588
|
+
{
|
|
2589
|
+
throw Iex::BaseExc("DC data corrupt.");
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
//
|
|
2594
|
+
// Uncompress the RLE data into _rleBuffer, then unRLE the results
|
|
2595
|
+
// into _planarUncBuffer[RLE]
|
|
2596
|
+
//
|
|
2597
|
+
|
|
2598
|
+
if (rleRawSize > 0)
|
|
2599
|
+
{
|
|
2600
|
+
if (rleUncompressedSize > _rleBufferSize ||
|
|
2601
|
+
rleRawSize > _planarUncBufferSize[RLE])
|
|
2602
|
+
{
|
|
2603
|
+
throw Iex::InputExc("Error uncompressing DWA data"
|
|
2604
|
+
"(corrupt header).");
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2607
|
+
uLongf dstLen = (uLongf)rleUncompressedSize;
|
|
2608
|
+
|
|
2609
|
+
if (Z_OK != ::uncompress
|
|
2610
|
+
((Bytef *)_rleBuffer,
|
|
2611
|
+
&dstLen,
|
|
2612
|
+
(Bytef *)compressedRleBuf,
|
|
2613
|
+
(uLong)rleCompressedSize))
|
|
2614
|
+
{
|
|
2615
|
+
throw Iex::BaseExc("Error uncompressing RLE data.");
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
if (dstLen != rleUncompressedSize)
|
|
2619
|
+
throw Iex::BaseExc("RLE data corrupted");
|
|
2620
|
+
|
|
2621
|
+
if (rleUncompress
|
|
2622
|
+
((int)rleUncompressedSize,
|
|
2623
|
+
(int)rleRawSize,
|
|
2624
|
+
(signed char *)_rleBuffer,
|
|
2625
|
+
_planarUncBuffer[RLE]) != rleRawSize)
|
|
2626
|
+
{
|
|
2627
|
+
throw Iex::BaseExc("RLE data corrupted");
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
//
|
|
2632
|
+
// Determine the start of each row in the output buffer
|
|
2633
|
+
//
|
|
2634
|
+
|
|
2635
|
+
std::vector<bool> decodedChannels (_channelData.size());
|
|
2636
|
+
std::vector< std::vector<char *> > rowPtrs (_channelData.size());
|
|
2637
|
+
|
|
2638
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
2639
|
+
decodedChannels[chan] = false;
|
|
2640
|
+
|
|
2641
|
+
outBufferEnd = _outBuffer;
|
|
2642
|
+
|
|
2643
|
+
for (int y = minY; y <= maxY; ++y)
|
|
2644
|
+
{
|
|
2645
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
2646
|
+
{
|
|
2647
|
+
ChannelData *cd = &_channelData[chan];
|
|
2648
|
+
|
|
2649
|
+
if (Imath::modp (y, cd->ySampling) != 0)
|
|
2650
|
+
continue;
|
|
2651
|
+
|
|
2652
|
+
rowPtrs[chan].push_back (outBufferEnd);
|
|
2653
|
+
outBufferEnd += cd->width * Imf::pixelTypeSize (cd->type);
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
//
|
|
2658
|
+
// Setup to decode each block of 3 channels that need to
|
|
2659
|
+
// be handled together
|
|
2660
|
+
//
|
|
2661
|
+
|
|
2662
|
+
for (unsigned int csc = 0; csc < _cscSets.size(); ++csc)
|
|
2663
|
+
{
|
|
2664
|
+
int rChan = _cscSets[csc].idx[0];
|
|
2665
|
+
int gChan = _cscSets[csc].idx[1];
|
|
2666
|
+
int bChan = _cscSets[csc].idx[2];
|
|
2667
|
+
|
|
2668
|
+
|
|
2669
|
+
LossyDctDecoderCsc decoder
|
|
2670
|
+
(rowPtrs[rChan],
|
|
2671
|
+
rowPtrs[gChan],
|
|
2672
|
+
rowPtrs[bChan],
|
|
2673
|
+
packedAcBufferEnd,
|
|
2674
|
+
packedDcBufferEnd,
|
|
2675
|
+
dwaCompressorToLinear,
|
|
2676
|
+
_channelData[rChan].width,
|
|
2677
|
+
_channelData[rChan].height,
|
|
2678
|
+
_channelData[rChan].type,
|
|
2679
|
+
_channelData[gChan].type,
|
|
2680
|
+
_channelData[bChan].type);
|
|
2681
|
+
|
|
2682
|
+
decoder.execute();
|
|
2683
|
+
|
|
2684
|
+
packedAcBufferEnd +=
|
|
2685
|
+
decoder.numAcValuesEncoded() * sizeof (unsigned short);
|
|
2686
|
+
|
|
2687
|
+
packedDcBufferEnd +=
|
|
2688
|
+
decoder.numDcValuesEncoded() * sizeof (unsigned short);
|
|
2689
|
+
|
|
2690
|
+
decodedChannels[rChan] = true;
|
|
2691
|
+
decodedChannels[gChan] = true;
|
|
2692
|
+
decodedChannels[bChan] = true;
|
|
2693
|
+
}
|
|
2694
|
+
|
|
2695
|
+
//
|
|
2696
|
+
// Setup to handle the remaining channels by themselves
|
|
2697
|
+
//
|
|
2698
|
+
|
|
2699
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
2700
|
+
{
|
|
2701
|
+
if (decodedChannels[chan])
|
|
2702
|
+
continue;
|
|
2703
|
+
|
|
2704
|
+
ChannelData *cd = &_channelData[chan];
|
|
2705
|
+
int pixelSize = Imf::pixelTypeSize (cd->type);
|
|
2706
|
+
|
|
2707
|
+
switch (cd->compression)
|
|
2708
|
+
{
|
|
2709
|
+
case LOSSY_DCT:
|
|
2710
|
+
|
|
2711
|
+
//
|
|
2712
|
+
// Setup a single-channel lossy DCT decoder pointing
|
|
2713
|
+
// at the output buffer
|
|
2714
|
+
//
|
|
2715
|
+
|
|
2716
|
+
{
|
|
2717
|
+
const unsigned short *linearLut = 0;
|
|
2718
|
+
|
|
2719
|
+
if (!cd->pLinear)
|
|
2720
|
+
linearLut = dwaCompressorToLinear;
|
|
2721
|
+
|
|
2722
|
+
LossyDctDecoder decoder
|
|
2723
|
+
(rowPtrs[chan],
|
|
2724
|
+
packedAcBufferEnd,
|
|
2725
|
+
packedDcBufferEnd,
|
|
2726
|
+
linearLut,
|
|
2727
|
+
cd->width,
|
|
2728
|
+
cd->height,
|
|
2729
|
+
cd->type);
|
|
2730
|
+
|
|
2731
|
+
decoder.execute();
|
|
2732
|
+
|
|
2733
|
+
packedAcBufferEnd +=
|
|
2734
|
+
decoder.numAcValuesEncoded() * sizeof (unsigned short);
|
|
2735
|
+
|
|
2736
|
+
packedDcBufferEnd +=
|
|
2737
|
+
decoder.numDcValuesEncoded() * sizeof (unsigned short);
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2740
|
+
break;
|
|
2741
|
+
|
|
2742
|
+
case RLE:
|
|
2743
|
+
|
|
2744
|
+
//
|
|
2745
|
+
// For the RLE case, the data has been un-RLE'd into
|
|
2746
|
+
// planarUncRleEnd[], but is still split out by bytes.
|
|
2747
|
+
// We need to rearrange the bytes back into the correct
|
|
2748
|
+
// order in the output buffer;
|
|
2749
|
+
//
|
|
2750
|
+
|
|
2751
|
+
{
|
|
2752
|
+
int row = 0;
|
|
2753
|
+
|
|
2754
|
+
for (int y = minY; y <= maxY; ++y)
|
|
2755
|
+
{
|
|
2756
|
+
if (Imath::modp (y, cd->ySampling) != 0)
|
|
2757
|
+
continue;
|
|
2758
|
+
|
|
2759
|
+
char *dst = rowPtrs[chan][row];
|
|
2760
|
+
|
|
2761
|
+
if (pixelSize == 2)
|
|
2762
|
+
{
|
|
2763
|
+
interleaveByte2 (dst,
|
|
2764
|
+
cd->planarUncRleEnd[0],
|
|
2765
|
+
cd->planarUncRleEnd[1],
|
|
2766
|
+
cd->width);
|
|
2767
|
+
|
|
2768
|
+
cd->planarUncRleEnd[0] += cd->width;
|
|
2769
|
+
cd->planarUncRleEnd[1] += cd->width;
|
|
2770
|
+
}
|
|
2771
|
+
else
|
|
2772
|
+
{
|
|
2773
|
+
for (int x = 0; x < cd->width; ++x)
|
|
2774
|
+
{
|
|
2775
|
+
for (int byte = 0; byte < pixelSize; ++byte)
|
|
2776
|
+
{
|
|
2777
|
+
*dst++ = *cd->planarUncRleEnd[byte]++;
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
row++;
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
|
|
2786
|
+
break;
|
|
2787
|
+
|
|
2788
|
+
case UNKNOWN:
|
|
2789
|
+
|
|
2790
|
+
//
|
|
2791
|
+
// In the UNKNOWN case, data is already in planarUncBufferEnd
|
|
2792
|
+
// and just needs to copied over to the output buffer
|
|
2793
|
+
//
|
|
2794
|
+
|
|
2795
|
+
{
|
|
2796
|
+
int row = 0;
|
|
2797
|
+
int dstScanlineSize = cd->width * Imf::pixelTypeSize (cd->type);
|
|
2798
|
+
|
|
2799
|
+
for (int y = minY; y <= maxY; ++y)
|
|
2800
|
+
{
|
|
2801
|
+
if (Imath::modp (y, cd->ySampling) != 0)
|
|
2802
|
+
continue;
|
|
2803
|
+
|
|
2804
|
+
memcpy (rowPtrs[chan][row],
|
|
2805
|
+
cd->planarUncBufferEnd,
|
|
2806
|
+
dstScanlineSize);
|
|
2807
|
+
|
|
2808
|
+
cd->planarUncBufferEnd += dstScanlineSize;
|
|
2809
|
+
row++;
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
break;
|
|
2814
|
+
|
|
2815
|
+
default:
|
|
2816
|
+
|
|
2817
|
+
throw Iex::NoImplExc ("Unhandled compression scheme case");
|
|
2818
|
+
break;
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
decodedChannels[chan] = true;
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
//
|
|
2825
|
+
// Return a ptr to _outBuffer
|
|
2826
|
+
//
|
|
2827
|
+
|
|
2828
|
+
outPtr = _outBuffer;
|
|
2829
|
+
return (int)(outBufferEnd - _outBuffer);
|
|
2830
|
+
}
|
|
2831
|
+
|
|
2832
|
+
|
|
2833
|
+
// static
|
|
2834
|
+
void
|
|
2835
|
+
DwaCompressor::initializeFuncs()
|
|
2836
|
+
{
|
|
2837
|
+
convertFloatToHalf64 = convertFloatToHalf64_scalar;
|
|
2838
|
+
fromHalfZigZag = fromHalfZigZag_scalar;
|
|
2839
|
+
|
|
2840
|
+
CpuId cpuId;
|
|
2841
|
+
|
|
2842
|
+
//
|
|
2843
|
+
// Setup HALF <-> FLOAT conversion implementations
|
|
2844
|
+
//
|
|
2845
|
+
|
|
2846
|
+
if (cpuId.avx && cpuId.f16c)
|
|
2847
|
+
{
|
|
2848
|
+
convertFloatToHalf64 = convertFloatToHalf64_f16c;
|
|
2849
|
+
fromHalfZigZag = fromHalfZigZag_f16c;
|
|
2850
|
+
}
|
|
2851
|
+
|
|
2852
|
+
//
|
|
2853
|
+
// Setup inverse DCT implementations
|
|
2854
|
+
//
|
|
2855
|
+
|
|
2856
|
+
dctInverse8x8_0 = dctInverse8x8_scalar<0>;
|
|
2857
|
+
dctInverse8x8_1 = dctInverse8x8_scalar<1>;
|
|
2858
|
+
dctInverse8x8_2 = dctInverse8x8_scalar<2>;
|
|
2859
|
+
dctInverse8x8_3 = dctInverse8x8_scalar<3>;
|
|
2860
|
+
dctInverse8x8_4 = dctInverse8x8_scalar<4>;
|
|
2861
|
+
dctInverse8x8_5 = dctInverse8x8_scalar<5>;
|
|
2862
|
+
dctInverse8x8_6 = dctInverse8x8_scalar<6>;
|
|
2863
|
+
dctInverse8x8_7 = dctInverse8x8_scalar<7>;
|
|
2864
|
+
|
|
2865
|
+
if (cpuId.avx)
|
|
2866
|
+
{
|
|
2867
|
+
dctInverse8x8_0 = dctInverse8x8_avx<0>;
|
|
2868
|
+
dctInverse8x8_1 = dctInverse8x8_avx<1>;
|
|
2869
|
+
dctInverse8x8_2 = dctInverse8x8_avx<2>;
|
|
2870
|
+
dctInverse8x8_3 = dctInverse8x8_avx<3>;
|
|
2871
|
+
dctInverse8x8_4 = dctInverse8x8_avx<4>;
|
|
2872
|
+
dctInverse8x8_5 = dctInverse8x8_avx<5>;
|
|
2873
|
+
dctInverse8x8_6 = dctInverse8x8_avx<6>;
|
|
2874
|
+
dctInverse8x8_7 = dctInverse8x8_avx<7>;
|
|
2875
|
+
}
|
|
2876
|
+
else if (cpuId.sse2)
|
|
2877
|
+
{
|
|
2878
|
+
dctInverse8x8_0 = dctInverse8x8_sse2<0>;
|
|
2879
|
+
dctInverse8x8_1 = dctInverse8x8_sse2<1>;
|
|
2880
|
+
dctInverse8x8_2 = dctInverse8x8_sse2<2>;
|
|
2881
|
+
dctInverse8x8_3 = dctInverse8x8_sse2<3>;
|
|
2882
|
+
dctInverse8x8_4 = dctInverse8x8_sse2<4>;
|
|
2883
|
+
dctInverse8x8_5 = dctInverse8x8_sse2<5>;
|
|
2884
|
+
dctInverse8x8_6 = dctInverse8x8_sse2<6>;
|
|
2885
|
+
dctInverse8x8_7 = dctInverse8x8_sse2<7>;
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2889
|
+
|
|
2890
|
+
//
|
|
2891
|
+
// Handle channel classification and buffer allocation once we know
|
|
2892
|
+
// how to classify channels
|
|
2893
|
+
//
|
|
2894
|
+
|
|
2895
|
+
void
|
|
2896
|
+
DwaCompressor::initializeBuffers (size_t &outBufferSize)
|
|
2897
|
+
{
|
|
2898
|
+
classifyChannels (_channels, _channelData, _cscSets);
|
|
2899
|
+
|
|
2900
|
+
//
|
|
2901
|
+
// _outBuffer needs to be big enough to hold all our
|
|
2902
|
+
// compressed data - which could vary depending on what sort
|
|
2903
|
+
// of channels we have.
|
|
2904
|
+
//
|
|
2905
|
+
|
|
2906
|
+
int maxOutBufferSize = 0;
|
|
2907
|
+
int numLossyDctChans = 0;
|
|
2908
|
+
int unknownBufferSize = 0;
|
|
2909
|
+
int rleBufferSize = 0;
|
|
2910
|
+
|
|
2911
|
+
int maxLossyDctAcSize = (int)ceil ((float)numScanLines() / 8.0f) *
|
|
2912
|
+
(int)ceil ((float)(_max[0] - _min[0] + 1) / 8.0f) *
|
|
2913
|
+
63 * sizeof (unsigned short);
|
|
2914
|
+
|
|
2915
|
+
int maxLossyDctDcSize = (int)ceil ((float)numScanLines() / 8.0f) *
|
|
2916
|
+
(int)ceil ((float)(_max[0] - _min[0] + 1) / 8.0f) *
|
|
2917
|
+
sizeof (unsigned short);
|
|
2918
|
+
|
|
2919
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
2920
|
+
{
|
|
2921
|
+
switch (_channelData[chan].compression)
|
|
2922
|
+
{
|
|
2923
|
+
case LOSSY_DCT:
|
|
2924
|
+
|
|
2925
|
+
//
|
|
2926
|
+
// This is the size of the number of packed
|
|
2927
|
+
// components, plus the requirements for
|
|
2928
|
+
// maximum Huffman encoding size.
|
|
2929
|
+
//
|
|
2930
|
+
|
|
2931
|
+
maxOutBufferSize += 2 * maxLossyDctAcSize + 65536;
|
|
2932
|
+
numLossyDctChans++;
|
|
2933
|
+
break;
|
|
2934
|
+
|
|
2935
|
+
case RLE:
|
|
2936
|
+
{
|
|
2937
|
+
//
|
|
2938
|
+
// RLE, if gone horribly wrong, could double the size
|
|
2939
|
+
// of the source data.
|
|
2940
|
+
//
|
|
2941
|
+
|
|
2942
|
+
int rleAmount = 2 * numScanLines() * (_max[0] - _min[0] + 1) *
|
|
2943
|
+
Imf::pixelTypeSize (_channelData[chan].type);
|
|
2944
|
+
|
|
2945
|
+
rleBufferSize += rleAmount;
|
|
2946
|
+
}
|
|
2947
|
+
break;
|
|
2948
|
+
|
|
2949
|
+
|
|
2950
|
+
case UNKNOWN:
|
|
2951
|
+
|
|
2952
|
+
unknownBufferSize += numScanLines() * (_max[0] - _min[0] + 1) *
|
|
2953
|
+
Imf::pixelTypeSize (_channelData[chan].type);
|
|
2954
|
+
break;
|
|
2955
|
+
|
|
2956
|
+
default:
|
|
2957
|
+
|
|
2958
|
+
throw Iex::NoImplExc ("Unhandled compression scheme case");
|
|
2959
|
+
break;
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
//
|
|
2964
|
+
// Also, since the results of the RLE are packed into
|
|
2965
|
+
// the output buffer, we need the extra room there. But
|
|
2966
|
+
// we're going to zlib compress() the data we pack,
|
|
2967
|
+
// which could take slightly more space
|
|
2968
|
+
//
|
|
2969
|
+
|
|
2970
|
+
maxOutBufferSize += (int)(ceil (1.01f * (float)rleBufferSize) + 100);
|
|
2971
|
+
|
|
2972
|
+
//
|
|
2973
|
+
// And the same goes for the UNKNOWN data
|
|
2974
|
+
//
|
|
2975
|
+
|
|
2976
|
+
maxOutBufferSize += (int)(ceil (1.01f * (float)unknownBufferSize) + 100);
|
|
2977
|
+
|
|
2978
|
+
//
|
|
2979
|
+
// Allocate a zip/deflate compressor big enought to hold the DC data
|
|
2980
|
+
// and include it's compressed results in the size requirements
|
|
2981
|
+
// for our output buffer
|
|
2982
|
+
//
|
|
2983
|
+
|
|
2984
|
+
if (_zip == 0)
|
|
2985
|
+
_zip = new Zip (maxLossyDctDcSize * numLossyDctChans);
|
|
2986
|
+
else if (_zip->maxRawSize() < maxLossyDctDcSize * numLossyDctChans)
|
|
2987
|
+
{
|
|
2988
|
+
delete _zip;
|
|
2989
|
+
_zip = new Zip (maxLossyDctDcSize * numLossyDctChans);
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
|
|
2993
|
+
maxOutBufferSize += _zip->maxCompressedSize();
|
|
2994
|
+
|
|
2995
|
+
//
|
|
2996
|
+
// We also need to reserve space at the head of the buffer to
|
|
2997
|
+
// write out the size of our various packed and compressed data.
|
|
2998
|
+
//
|
|
2999
|
+
|
|
3000
|
+
maxOutBufferSize += NUM_SIZES_SINGLE * sizeof (Int64);
|
|
3001
|
+
|
|
3002
|
+
|
|
3003
|
+
//
|
|
3004
|
+
// Later, we're going to hijack outBuffer for the result of
|
|
3005
|
+
// both encoding and decoding. So it needs to be big enough
|
|
3006
|
+
// to hold either a buffers' worth of uncompressed or
|
|
3007
|
+
// compressed data
|
|
3008
|
+
//
|
|
3009
|
+
// For encoding, we'll need _outBuffer to hold maxOutBufferSize bytes,
|
|
3010
|
+
// but for decoding, we only need it to be maxScanLineSize*numScanLines.
|
|
3011
|
+
// Cache the max size for now, and alloc the buffer when we either
|
|
3012
|
+
// encode or decode.
|
|
3013
|
+
//
|
|
3014
|
+
|
|
3015
|
+
outBufferSize = maxOutBufferSize;
|
|
3016
|
+
|
|
3017
|
+
|
|
3018
|
+
//
|
|
3019
|
+
// _packedAcBuffer holds the quantized DCT coefficients prior
|
|
3020
|
+
// to Huffman encoding
|
|
3021
|
+
//
|
|
3022
|
+
|
|
3023
|
+
if (maxLossyDctAcSize * numLossyDctChans > _packedAcBufferSize)
|
|
3024
|
+
{
|
|
3025
|
+
_packedAcBufferSize = maxLossyDctAcSize * numLossyDctChans;
|
|
3026
|
+
if (_packedAcBuffer != 0)
|
|
3027
|
+
delete[] _packedAcBuffer;
|
|
3028
|
+
_packedAcBuffer = new char[_packedAcBufferSize];
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
//
|
|
3032
|
+
// _packedDcBuffer holds one quantized DCT coef per 8x8 block
|
|
3033
|
+
//
|
|
3034
|
+
|
|
3035
|
+
if (maxLossyDctDcSize * numLossyDctChans > _packedDcBufferSize)
|
|
3036
|
+
{
|
|
3037
|
+
_packedDcBufferSize = maxLossyDctDcSize * numLossyDctChans;
|
|
3038
|
+
if (_packedDcBuffer != 0)
|
|
3039
|
+
delete[] _packedDcBuffer;
|
|
3040
|
+
_packedDcBuffer = new char[_packedDcBufferSize];
|
|
3041
|
+
}
|
|
3042
|
+
|
|
3043
|
+
if (rleBufferSize > _rleBufferSize)
|
|
3044
|
+
{
|
|
3045
|
+
_rleBufferSize = rleBufferSize;
|
|
3046
|
+
if (_rleBuffer != 0)
|
|
3047
|
+
delete[] _rleBuffer;
|
|
3048
|
+
_rleBuffer = new char[rleBufferSize];
|
|
3049
|
+
}
|
|
3050
|
+
|
|
3051
|
+
//
|
|
3052
|
+
// The planar uncompressed buffer will hold float data for LOSSY_DCT
|
|
3053
|
+
// compressed values, and whatever the native type is for other
|
|
3054
|
+
// channels. We're going to use this to hold data in a planar
|
|
3055
|
+
// format, as opposed to the native interleaved format we take
|
|
3056
|
+
// into compress() and give back from uncompress().
|
|
3057
|
+
//
|
|
3058
|
+
// This also makes it easier to compress the UNKNOWN and RLE data
|
|
3059
|
+
// all in one swoop (for each compression scheme).
|
|
3060
|
+
//
|
|
3061
|
+
|
|
3062
|
+
int planarUncBufferSize[NUM_COMPRESSOR_SCHEMES];
|
|
3063
|
+
for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
|
|
3064
|
+
planarUncBufferSize[i] = 0;
|
|
3065
|
+
|
|
3066
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
3067
|
+
{
|
|
3068
|
+
switch (_channelData[chan].compression)
|
|
3069
|
+
{
|
|
3070
|
+
case LOSSY_DCT:
|
|
3071
|
+
break;
|
|
3072
|
+
|
|
3073
|
+
case RLE:
|
|
3074
|
+
planarUncBufferSize[RLE] +=
|
|
3075
|
+
numScanLines() * (_max[0] - _min[0] + 1) *
|
|
3076
|
+
Imf::pixelTypeSize (_channelData[chan].type);
|
|
3077
|
+
break;
|
|
3078
|
+
|
|
3079
|
+
case UNKNOWN:
|
|
3080
|
+
planarUncBufferSize[UNKNOWN] +=
|
|
3081
|
+
numScanLines() * (_max[0] - _min[0] + 1) *
|
|
3082
|
+
Imf::pixelTypeSize (_channelData[chan].type);
|
|
3083
|
+
break;
|
|
3084
|
+
|
|
3085
|
+
default:
|
|
3086
|
+
throw Iex::NoImplExc ("Unhandled compression scheme case");
|
|
3087
|
+
break;
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
|
|
3091
|
+
//
|
|
3092
|
+
// UNKNOWN data is going to be zlib compressed, which needs
|
|
3093
|
+
// a little extra headroom
|
|
3094
|
+
//
|
|
3095
|
+
|
|
3096
|
+
if (planarUncBufferSize[UNKNOWN] > 0)
|
|
3097
|
+
{
|
|
3098
|
+
planarUncBufferSize[UNKNOWN] =
|
|
3099
|
+
(int) ceil (1.01f * (float)planarUncBufferSize[UNKNOWN]) + 100;
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
for (int i = 0; i < NUM_COMPRESSOR_SCHEMES; ++i)
|
|
3103
|
+
{
|
|
3104
|
+
if (planarUncBufferSize[i] > _planarUncBufferSize[i])
|
|
3105
|
+
{
|
|
3106
|
+
_planarUncBufferSize[i] = planarUncBufferSize[i];
|
|
3107
|
+
if (_planarUncBuffer[i] != 0)
|
|
3108
|
+
delete[] _planarUncBuffer[i];
|
|
3109
|
+
_planarUncBuffer[i] = new char[planarUncBufferSize[i]];
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
}
|
|
3113
|
+
|
|
3114
|
+
|
|
3115
|
+
//
|
|
3116
|
+
// Setup channel classification rules to use when writing files
|
|
3117
|
+
//
|
|
3118
|
+
|
|
3119
|
+
void
|
|
3120
|
+
DwaCompressor::initializeDefaultChannelRules ()
|
|
3121
|
+
{
|
|
3122
|
+
_channelRules.clear();
|
|
3123
|
+
|
|
3124
|
+
_channelRules.push_back (Classifier ("R", LOSSY_DCT, HALF, 0, false));
|
|
3125
|
+
_channelRules.push_back (Classifier ("R", LOSSY_DCT, FLOAT, 0, false));
|
|
3126
|
+
_channelRules.push_back (Classifier ("G", LOSSY_DCT, HALF, 1, false));
|
|
3127
|
+
_channelRules.push_back (Classifier ("G", LOSSY_DCT, FLOAT, 1, false));
|
|
3128
|
+
_channelRules.push_back (Classifier ("B", LOSSY_DCT, HALF, 2, false));
|
|
3129
|
+
_channelRules.push_back (Classifier ("B", LOSSY_DCT, FLOAT, 2, false));
|
|
3130
|
+
|
|
3131
|
+
_channelRules.push_back (Classifier ("Y", LOSSY_DCT, HALF, -1, false));
|
|
3132
|
+
_channelRules.push_back (Classifier ("Y", LOSSY_DCT, FLOAT, -1, false));
|
|
3133
|
+
_channelRules.push_back (Classifier ("BY", LOSSY_DCT, HALF, -1, false));
|
|
3134
|
+
_channelRules.push_back (Classifier ("BY", LOSSY_DCT, FLOAT, -1, false));
|
|
3135
|
+
_channelRules.push_back (Classifier ("RY", LOSSY_DCT, HALF, -1, false));
|
|
3136
|
+
_channelRules.push_back (Classifier ("RY", LOSSY_DCT, FLOAT, -1, false));
|
|
3137
|
+
|
|
3138
|
+
_channelRules.push_back (Classifier ("A", RLE, UINT, -1, false));
|
|
3139
|
+
_channelRules.push_back (Classifier ("A", RLE, HALF, -1, false));
|
|
3140
|
+
_channelRules.push_back (Classifier ("A", RLE, FLOAT, -1, false));
|
|
3141
|
+
}
|
|
3142
|
+
|
|
3143
|
+
|
|
3144
|
+
//
|
|
3145
|
+
// Setup channel classification rules when reading files with VERSION < 2
|
|
3146
|
+
//
|
|
3147
|
+
|
|
3148
|
+
void
|
|
3149
|
+
DwaCompressor::initializeLegacyChannelRules ()
|
|
3150
|
+
{
|
|
3151
|
+
_channelRules.clear();
|
|
3152
|
+
|
|
3153
|
+
_channelRules.push_back (Classifier ("r", LOSSY_DCT, HALF, 0, true));
|
|
3154
|
+
_channelRules.push_back (Classifier ("r", LOSSY_DCT, FLOAT, 0, true));
|
|
3155
|
+
_channelRules.push_back (Classifier ("red", LOSSY_DCT, HALF, 0, true));
|
|
3156
|
+
_channelRules.push_back (Classifier ("red", LOSSY_DCT, FLOAT, 0, true));
|
|
3157
|
+
_channelRules.push_back (Classifier ("g", LOSSY_DCT, HALF, 1, true));
|
|
3158
|
+
_channelRules.push_back (Classifier ("g", LOSSY_DCT, FLOAT, 1, true));
|
|
3159
|
+
_channelRules.push_back (Classifier ("grn", LOSSY_DCT, HALF, 1, true));
|
|
3160
|
+
_channelRules.push_back (Classifier ("grn", LOSSY_DCT, FLOAT, 1, true));
|
|
3161
|
+
_channelRules.push_back (Classifier ("green", LOSSY_DCT, HALF, 1, true));
|
|
3162
|
+
_channelRules.push_back (Classifier ("green", LOSSY_DCT, FLOAT, 1, true));
|
|
3163
|
+
_channelRules.push_back (Classifier ("b", LOSSY_DCT, HALF, 2, true));
|
|
3164
|
+
_channelRules.push_back (Classifier ("b", LOSSY_DCT, FLOAT, 2, true));
|
|
3165
|
+
_channelRules.push_back (Classifier ("blu", LOSSY_DCT, HALF, 2, true));
|
|
3166
|
+
_channelRules.push_back (Classifier ("blu", LOSSY_DCT, FLOAT, 2, true));
|
|
3167
|
+
_channelRules.push_back (Classifier ("blue", LOSSY_DCT, HALF, 2, true));
|
|
3168
|
+
_channelRules.push_back (Classifier ("blue", LOSSY_DCT, FLOAT, 2, true));
|
|
3169
|
+
|
|
3170
|
+
_channelRules.push_back (Classifier ("y", LOSSY_DCT, HALF, -1, true));
|
|
3171
|
+
_channelRules.push_back (Classifier ("y", LOSSY_DCT, FLOAT, -1, true));
|
|
3172
|
+
_channelRules.push_back (Classifier ("by", LOSSY_DCT, HALF, -1, true));
|
|
3173
|
+
_channelRules.push_back (Classifier ("by", LOSSY_DCT, FLOAT, -1, true));
|
|
3174
|
+
_channelRules.push_back (Classifier ("ry", LOSSY_DCT, HALF, -1, true));
|
|
3175
|
+
_channelRules.push_back (Classifier ("ry", LOSSY_DCT, FLOAT, -1, true));
|
|
3176
|
+
_channelRules.push_back (Classifier ("a", RLE, UINT, -1, true));
|
|
3177
|
+
_channelRules.push_back (Classifier ("a", RLE, HALF, -1, true));
|
|
3178
|
+
_channelRules.push_back (Classifier ("a", RLE, FLOAT, -1, true));
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
|
|
3182
|
+
//
|
|
3183
|
+
// Given a set of rules and ChannelData, figure out which rules apply
|
|
3184
|
+
//
|
|
3185
|
+
|
|
3186
|
+
void
|
|
3187
|
+
DwaCompressor::relevantChannelRules (std::vector<Classifier> &rules) const
|
|
3188
|
+
{
|
|
3189
|
+
rules.clear();
|
|
3190
|
+
|
|
3191
|
+
std::vector<std::string> suffixes;
|
|
3192
|
+
|
|
3193
|
+
for (size_t cd = 0; cd < _channelData.size(); ++cd)
|
|
3194
|
+
{
|
|
3195
|
+
std::string suffix = _channelData[cd].name;
|
|
3196
|
+
size_t lastDot = suffix.find_last_of ('.');
|
|
3197
|
+
|
|
3198
|
+
if (lastDot != std::string::npos)
|
|
3199
|
+
suffix = suffix.substr (lastDot+1, std::string::npos);
|
|
3200
|
+
|
|
3201
|
+
suffixes.push_back(suffix);
|
|
3202
|
+
}
|
|
3203
|
+
|
|
3204
|
+
|
|
3205
|
+
for (size_t i = 0; i < _channelRules.size(); ++i)
|
|
3206
|
+
{
|
|
3207
|
+
for (size_t cd = 0; cd < _channelData.size(); ++cd)
|
|
3208
|
+
{
|
|
3209
|
+
if (_channelRules[i].match (suffixes[cd], _channelData[cd].type ))
|
|
3210
|
+
{
|
|
3211
|
+
rules.push_back (_channelRules[i]);
|
|
3212
|
+
break;
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
|
|
3219
|
+
//
|
|
3220
|
+
// Take our initial list of channels, and cache the contents.
|
|
3221
|
+
//
|
|
3222
|
+
// Determine approprate compression schemes for each channel,
|
|
3223
|
+
// and figure out which sets should potentially be CSC'ed
|
|
3224
|
+
// prior to lossy compression.
|
|
3225
|
+
//
|
|
3226
|
+
|
|
3227
|
+
void
|
|
3228
|
+
DwaCompressor::classifyChannels
|
|
3229
|
+
(ChannelList channels,
|
|
3230
|
+
std::vector<ChannelData> &chanData,
|
|
3231
|
+
std::vector<CscChannelSet> &cscData)
|
|
3232
|
+
{
|
|
3233
|
+
//
|
|
3234
|
+
// prefixMap used to map channel name prefixes to
|
|
3235
|
+
// potential CSC-able sets of channels.
|
|
3236
|
+
//
|
|
3237
|
+
|
|
3238
|
+
std::map<std::string, DwaCompressor::CscChannelSet> prefixMap;
|
|
3239
|
+
std::vector<DwaCompressor::CscChannelSet> tmpCscSet;
|
|
3240
|
+
|
|
3241
|
+
unsigned int numChan = 0;
|
|
3242
|
+
|
|
3243
|
+
for (ChannelList::Iterator c = channels.begin(); c != channels.end(); ++c)
|
|
3244
|
+
numChan++;
|
|
3245
|
+
|
|
3246
|
+
if (numChan)
|
|
3247
|
+
chanData.resize (numChan);
|
|
3248
|
+
|
|
3249
|
+
//
|
|
3250
|
+
// Cache the relevant data from the channel structs.
|
|
3251
|
+
//
|
|
3252
|
+
|
|
3253
|
+
unsigned int offset = 0;
|
|
3254
|
+
|
|
3255
|
+
for (ChannelList::Iterator c = channels.begin(); c != channels.end(); ++c)
|
|
3256
|
+
{
|
|
3257
|
+
chanData[offset].name = std::string (c.name());
|
|
3258
|
+
chanData[offset].compression = UNKNOWN;
|
|
3259
|
+
chanData[offset].xSampling = c.channel().xSampling;
|
|
3260
|
+
chanData[offset].ySampling = c.channel().ySampling;
|
|
3261
|
+
chanData[offset].type = c.channel().type;
|
|
3262
|
+
chanData[offset].pLinear = c.channel().pLinear;
|
|
3263
|
+
|
|
3264
|
+
offset++;
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3267
|
+
//
|
|
3268
|
+
// Try and figure out which channels should be
|
|
3269
|
+
// compressed by which means.
|
|
3270
|
+
//
|
|
3271
|
+
|
|
3272
|
+
for (offset = 0; offset<numChan; ++offset)
|
|
3273
|
+
{
|
|
3274
|
+
std::string prefix = "";
|
|
3275
|
+
std::string suffix = chanData[offset].name;
|
|
3276
|
+
size_t lastDot = suffix.find_last_of ('.');
|
|
3277
|
+
|
|
3278
|
+
if (lastDot != std::string::npos)
|
|
3279
|
+
{
|
|
3280
|
+
prefix = suffix.substr (0, lastDot);
|
|
3281
|
+
suffix = suffix.substr (lastDot+1, std::string::npos);
|
|
3282
|
+
}
|
|
3283
|
+
|
|
3284
|
+
//
|
|
3285
|
+
// Make sure we have an entry in our CSC set map
|
|
3286
|
+
//
|
|
3287
|
+
|
|
3288
|
+
std::map<std::string, DwaCompressor::CscChannelSet>::iterator
|
|
3289
|
+
theSet = prefixMap.find (prefix);
|
|
3290
|
+
|
|
3291
|
+
if (theSet == prefixMap.end())
|
|
3292
|
+
{
|
|
3293
|
+
DwaCompressor::CscChannelSet tmpSet;
|
|
3294
|
+
|
|
3295
|
+
tmpSet.idx[0] =
|
|
3296
|
+
tmpSet.idx[1] =
|
|
3297
|
+
tmpSet.idx[2] = -1;
|
|
3298
|
+
|
|
3299
|
+
prefixMap[prefix] = tmpSet;
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3302
|
+
//
|
|
3303
|
+
// Check the suffix against the list of classifications
|
|
3304
|
+
// we defined previously. If the _cscIdx is not negative,
|
|
3305
|
+
// it indicates that we should be part of a CSC group.
|
|
3306
|
+
//
|
|
3307
|
+
|
|
3308
|
+
for (std::vector<Classifier>::iterator i = _channelRules.begin();
|
|
3309
|
+
i != _channelRules.end();
|
|
3310
|
+
++i)
|
|
3311
|
+
{
|
|
3312
|
+
if ( i->match(suffix, chanData[offset].type) )
|
|
3313
|
+
{
|
|
3314
|
+
chanData[offset].compression = i->_scheme;
|
|
3315
|
+
|
|
3316
|
+
if ( i->_cscIdx >= 0)
|
|
3317
|
+
prefixMap[prefix].idx[i->_cscIdx] = offset;
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
//
|
|
3323
|
+
// Finally, try and find RGB sets of channels which
|
|
3324
|
+
// can be CSC'ed to a Y'CbCr space prior to loss, for
|
|
3325
|
+
// better compression.
|
|
3326
|
+
//
|
|
3327
|
+
// Walk over our set of candidates, and see who has
|
|
3328
|
+
// all three channels defined (and has common sampling
|
|
3329
|
+
// patterns, etc).
|
|
3330
|
+
//
|
|
3331
|
+
|
|
3332
|
+
for (std::map<std::string, DwaCompressor::CscChannelSet>::iterator
|
|
3333
|
+
theItem = prefixMap.begin(); theItem != prefixMap.end();
|
|
3334
|
+
++theItem)
|
|
3335
|
+
{
|
|
3336
|
+
int red = (*theItem).second.idx[0];
|
|
3337
|
+
int grn = (*theItem).second.idx[1];
|
|
3338
|
+
int blu = (*theItem).second.idx[2];
|
|
3339
|
+
|
|
3340
|
+
if ((red < 0) || (grn < 0) || (blu < 0))
|
|
3341
|
+
continue;
|
|
3342
|
+
|
|
3343
|
+
if ((chanData[red].xSampling != chanData[grn].xSampling) ||
|
|
3344
|
+
(chanData[red].xSampling != chanData[blu].xSampling) ||
|
|
3345
|
+
(chanData[grn].xSampling != chanData[blu].xSampling) ||
|
|
3346
|
+
(chanData[red].ySampling != chanData[grn].ySampling) ||
|
|
3347
|
+
(chanData[red].ySampling != chanData[blu].ySampling) ||
|
|
3348
|
+
(chanData[grn].ySampling != chanData[blu].ySampling))
|
|
3349
|
+
{
|
|
3350
|
+
continue;
|
|
3351
|
+
}
|
|
3352
|
+
|
|
3353
|
+
tmpCscSet.push_back ((*theItem).second);
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3356
|
+
size_t numCsc = tmpCscSet.size();
|
|
3357
|
+
|
|
3358
|
+
if (numCsc)
|
|
3359
|
+
cscData.resize(numCsc);
|
|
3360
|
+
|
|
3361
|
+
for (offset = 0; offset < numCsc; ++offset)
|
|
3362
|
+
cscData[offset] = tmpCscSet[offset];
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
|
|
3366
|
+
|
|
3367
|
+
//
|
|
3368
|
+
// Setup some buffer pointers, determine channel sizes, things
|
|
3369
|
+
// like that.
|
|
3370
|
+
//
|
|
3371
|
+
|
|
3372
|
+
void
|
|
3373
|
+
DwaCompressor::setupChannelData (int minX, int minY, int maxX, int maxY)
|
|
3374
|
+
{
|
|
3375
|
+
char *planarUncBuffer[NUM_COMPRESSOR_SCHEMES];
|
|
3376
|
+
|
|
3377
|
+
for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
|
|
3378
|
+
{
|
|
3379
|
+
planarUncBuffer[i] = 0;
|
|
3380
|
+
|
|
3381
|
+
if (_planarUncBuffer[i])
|
|
3382
|
+
planarUncBuffer[i] = _planarUncBuffer[i];
|
|
3383
|
+
}
|
|
3384
|
+
|
|
3385
|
+
for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
|
|
3386
|
+
{
|
|
3387
|
+
ChannelData *cd = &_channelData[chan];
|
|
3388
|
+
|
|
3389
|
+
cd->width = Imf::numSamples (cd->xSampling, minX, maxX);
|
|
3390
|
+
cd->height = Imf::numSamples (cd->ySampling, minY, maxY);
|
|
3391
|
+
|
|
3392
|
+
cd->planarUncSize =
|
|
3393
|
+
cd->width * cd->height * Imf::pixelTypeSize (cd->type);
|
|
3394
|
+
|
|
3395
|
+
cd->planarUncBuffer = planarUncBuffer[cd->compression];
|
|
3396
|
+
cd->planarUncBufferEnd = cd->planarUncBuffer;
|
|
3397
|
+
|
|
3398
|
+
cd->planarUncRle[0] = cd->planarUncBuffer;
|
|
3399
|
+
cd->planarUncRleEnd[0] = cd->planarUncRle[0];
|
|
3400
|
+
|
|
3401
|
+
for (int byte = 1; byte < Imf::pixelTypeSize(cd->type); ++byte)
|
|
3402
|
+
{
|
|
3403
|
+
cd->planarUncRle[byte] =
|
|
3404
|
+
cd->planarUncRle[byte-1] + cd->width * cd->height;
|
|
3405
|
+
|
|
3406
|
+
cd->planarUncRleEnd[byte] =
|
|
3407
|
+
cd->planarUncRle[byte];
|
|
3408
|
+
}
|
|
3409
|
+
|
|
3410
|
+
cd->planarUncType = cd->type;
|
|
3411
|
+
|
|
3412
|
+
if (cd->compression == LOSSY_DCT)
|
|
3413
|
+
{
|
|
3414
|
+
cd->planarUncType = FLOAT;
|
|
3415
|
+
}
|
|
3416
|
+
else
|
|
3417
|
+
{
|
|
3418
|
+
planarUncBuffer[cd->compression] +=
|
|
3419
|
+
cd->width * cd->height * Imf::pixelTypeSize (cd->planarUncType);
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
|
|
3424
|
+
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
|