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,2631 @@
|
|
|
1
|
+
// ==========================================================
|
|
2
|
+
// TIFF Loader and Writer
|
|
3
|
+
//
|
|
4
|
+
// Design and implementation by
|
|
5
|
+
// - Floris van den Berg (flvdberg@wxs.nl)
|
|
6
|
+
// - Hervé Drolon (drolon@infonie.fr)
|
|
7
|
+
// - Markus Loibl (markus.loibl@epost.de)
|
|
8
|
+
// - Luca Piergentili (l.pierge@terra.es)
|
|
9
|
+
// - Detlev Vendt (detlev.vendt@brillit.de)
|
|
10
|
+
// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
|
|
11
|
+
//
|
|
12
|
+
// This file is part of FreeImage 3
|
|
13
|
+
//
|
|
14
|
+
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
|
|
15
|
+
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
|
|
16
|
+
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
|
|
17
|
+
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
|
|
18
|
+
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
|
|
19
|
+
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
|
|
20
|
+
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
|
|
21
|
+
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
|
|
22
|
+
// THIS DISCLAIMER.
|
|
23
|
+
//
|
|
24
|
+
// Use at your own risk!
|
|
25
|
+
// ==========================================================
|
|
26
|
+
|
|
27
|
+
#ifdef _MSC_VER
|
|
28
|
+
#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
#ifdef unix
|
|
32
|
+
#undef unix
|
|
33
|
+
#endif
|
|
34
|
+
#ifdef __unix
|
|
35
|
+
#undef __unix
|
|
36
|
+
#endif
|
|
37
|
+
|
|
38
|
+
#include "FreeImage.h"
|
|
39
|
+
#include "Utilities.h"
|
|
40
|
+
#include "../LibTIFF4/tiffiop.h"
|
|
41
|
+
#include "../Metadata/FreeImageTag.h"
|
|
42
|
+
#include "../OpenEXR/Half/half.h"
|
|
43
|
+
|
|
44
|
+
#include "FreeImageIO.h"
|
|
45
|
+
#include "PSDParser.h"
|
|
46
|
+
|
|
47
|
+
// --------------------------------------------------------------------------
|
|
48
|
+
// GeoTIFF profile (see XTIFF.cpp)
|
|
49
|
+
// --------------------------------------------------------------------------
|
|
50
|
+
void XTIFFInitialize();
|
|
51
|
+
BOOL tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib);
|
|
52
|
+
BOOL tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib);
|
|
53
|
+
|
|
54
|
+
// --------------------------------------------------------------------------
|
|
55
|
+
// TIFF Exif profile (see XTIFF.cpp)
|
|
56
|
+
// ----------------------------------------------------------
|
|
57
|
+
BOOL tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib);
|
|
58
|
+
BOOL tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib);
|
|
59
|
+
|
|
60
|
+
// --------------------------------------------------------------------------
|
|
61
|
+
// LogLuv conversion functions interface (see TIFFLogLuv.cpp)
|
|
62
|
+
// --------------------------------------------------------------------------
|
|
63
|
+
void tiff_ConvertLineXYZToRGB(BYTE *target, BYTE *source, double stonits, int width_in_pixels);
|
|
64
|
+
void tiff_ConvertLineRGBToXYZ(BYTE *target, BYTE *source, int width_in_pixels);
|
|
65
|
+
|
|
66
|
+
// ----------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
/** Supported loading methods */
|
|
69
|
+
typedef enum {
|
|
70
|
+
LoadAsRBGA = 0,
|
|
71
|
+
LoadAsCMYK = 1,
|
|
72
|
+
LoadAs8BitTrns = 2,
|
|
73
|
+
LoadAsGenericStrip = 3,
|
|
74
|
+
LoadAsTiled = 4,
|
|
75
|
+
LoadAsLogLuv = 5,
|
|
76
|
+
LoadAsHalfFloat = 6
|
|
77
|
+
} TIFFLoadMethod;
|
|
78
|
+
|
|
79
|
+
// ----------------------------------------------------------
|
|
80
|
+
// local prototypes
|
|
81
|
+
// ----------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
static tmsize_t _tiffReadProc(thandle_t handle, void* buf, tmsize_t size);
|
|
84
|
+
static tmsize_t _tiffWriteProc(thandle_t handle, void* buf, tmsize_t size);
|
|
85
|
+
static toff_t _tiffSeekProc(thandle_t handle, toff_t off, int whence);
|
|
86
|
+
static int _tiffCloseProc(thandle_t fd);
|
|
87
|
+
static int _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize);
|
|
88
|
+
static void _tiffUnmapProc(thandle_t fd, void* base, toff_t size);
|
|
89
|
+
|
|
90
|
+
static uint16 CheckColormap(int n, uint16* r, uint16* g, uint16* b);
|
|
91
|
+
static uint16 GetPhotometric(FIBITMAP *dib);
|
|
92
|
+
|
|
93
|
+
static void ReadResolution(TIFF *tiff, FIBITMAP *dib);
|
|
94
|
+
static void WriteResolution(TIFF *tiff, FIBITMAP *dib);
|
|
95
|
+
|
|
96
|
+
static void ReadPalette(TIFF *tiff, uint16 photometric, uint16 bitspersample, FIBITMAP *dib);
|
|
97
|
+
|
|
98
|
+
static FIBITMAP* CreateImageType(BOOL header_only, FREE_IMAGE_TYPE fit, int width, int height, uint16 bitspersample, uint16 samplesperpixel);
|
|
99
|
+
static FREE_IMAGE_TYPE ReadImageType(TIFF *tiff, uint16 bitspersample, uint16 samplesperpixel);
|
|
100
|
+
static void WriteImageType(TIFF *tiff, FREE_IMAGE_TYPE fit);
|
|
101
|
+
|
|
102
|
+
static void WriteCompression(TIFF *tiff, uint16 bitspersample, uint16 samplesperpixel, uint16 photometric, int flags);
|
|
103
|
+
|
|
104
|
+
static BOOL tiff_read_iptc_profile(TIFF *tiff, FIBITMAP *dib);
|
|
105
|
+
static BOOL tiff_read_xmp_profile(TIFF *tiff, FIBITMAP *dib);
|
|
106
|
+
static BOOL tiff_read_exif_profile(TIFF *tiff, FIBITMAP *dib);
|
|
107
|
+
static void ReadMetadata(TIFF *tiff, FIBITMAP *dib);
|
|
108
|
+
|
|
109
|
+
static BOOL tiff_write_iptc_profile(TIFF *tiff, FIBITMAP *dib);
|
|
110
|
+
static BOOL tiff_write_xmp_profile(TIFF *tiff, FIBITMAP *dib);
|
|
111
|
+
static void WriteMetadata(TIFF *tiff, FIBITMAP *dib);
|
|
112
|
+
|
|
113
|
+
static TIFFLoadMethod FindLoadMethod(TIFF *tif, uint16 photometric, uint16 bitspersample, uint16 samplesperpixel, FREE_IMAGE_TYPE image_type, int flags);
|
|
114
|
+
|
|
115
|
+
static void ReadThumbnail(FreeImageIO *io, fi_handle handle, void *data, TIFF *tiff, FIBITMAP *dib);
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
// ==========================================================
|
|
119
|
+
// Plugin Interface
|
|
120
|
+
// ==========================================================
|
|
121
|
+
|
|
122
|
+
static int s_format_id;
|
|
123
|
+
|
|
124
|
+
typedef struct {
|
|
125
|
+
FreeImageIO *io;
|
|
126
|
+
fi_handle handle;
|
|
127
|
+
TIFF *tif;
|
|
128
|
+
} fi_TIFFIO;
|
|
129
|
+
|
|
130
|
+
// ----------------------------------------------------------
|
|
131
|
+
// libtiff interface
|
|
132
|
+
// ----------------------------------------------------------
|
|
133
|
+
|
|
134
|
+
static tmsize_t
|
|
135
|
+
_tiffReadProc(thandle_t handle, void *buf, tmsize_t size) {
|
|
136
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)handle;
|
|
137
|
+
return fio->io->read_proc(buf, (unsigned)size, 1, fio->handle) * size;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static tmsize_t
|
|
141
|
+
_tiffWriteProc(thandle_t handle, void *buf, tmsize_t size) {
|
|
142
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)handle;
|
|
143
|
+
return fio->io->write_proc(buf, (unsigned)size, 1, fio->handle) * size;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
static toff_t
|
|
147
|
+
_tiffSeekProc(thandle_t handle, toff_t off, int whence) {
|
|
148
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)handle;
|
|
149
|
+
fio->io->seek_proc(fio->handle, (long)off, whence);
|
|
150
|
+
return fio->io->tell_proc(fio->handle);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static int
|
|
154
|
+
_tiffCloseProc(thandle_t fd) {
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
#include <sys/stat.h>
|
|
159
|
+
|
|
160
|
+
static toff_t
|
|
161
|
+
_tiffSizeProc(thandle_t handle) {
|
|
162
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)handle;
|
|
163
|
+
long currPos = fio->io->tell_proc(fio->handle);
|
|
164
|
+
fio->io->seek_proc(fio->handle, 0, SEEK_END);
|
|
165
|
+
long fileSize = fio->io->tell_proc(fio->handle);
|
|
166
|
+
fio->io->seek_proc(fio->handle, currPos, SEEK_SET);
|
|
167
|
+
return fileSize;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static int
|
|
171
|
+
_tiffMapProc(thandle_t, void** base, toff_t* size) {
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
static void
|
|
176
|
+
_tiffUnmapProc(thandle_t, void* base, toff_t size) {
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
Open a TIFF file descriptor for reading or writing
|
|
181
|
+
@param handle File handle
|
|
182
|
+
@param name Name of the file handle
|
|
183
|
+
@param mode Specifies if the file is to be opened for reading ("r") or writing ("w")
|
|
184
|
+
*/
|
|
185
|
+
TIFF *
|
|
186
|
+
TIFFFdOpen(thandle_t handle, const char *name, const char *mode) {
|
|
187
|
+
TIFF *tif;
|
|
188
|
+
|
|
189
|
+
// Open the file; the callback will set everything up
|
|
190
|
+
tif = TIFFClientOpen(name, mode, handle,
|
|
191
|
+
_tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
|
|
192
|
+
_tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
|
|
193
|
+
|
|
194
|
+
return tif;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
Open a TIFF file for reading or writing
|
|
199
|
+
@param name
|
|
200
|
+
@param mode
|
|
201
|
+
*/
|
|
202
|
+
TIFF*
|
|
203
|
+
TIFFOpen(const char* name, const char* mode) {
|
|
204
|
+
return 0;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// ----------------------------------------------------------
|
|
208
|
+
// TIFF library FreeImage-specific routines.
|
|
209
|
+
// ----------------------------------------------------------
|
|
210
|
+
|
|
211
|
+
void*
|
|
212
|
+
_TIFFmalloc(tmsize_t s) {
|
|
213
|
+
return malloc(s);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
void
|
|
217
|
+
_TIFFfree(void *p) {
|
|
218
|
+
free(p);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
void*
|
|
222
|
+
_TIFFrealloc(void* p, tmsize_t s) {
|
|
223
|
+
return realloc(p, s);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
void
|
|
227
|
+
_TIFFmemset(void* p, int v, tmsize_t c) {
|
|
228
|
+
memset(p, v, (size_t) c);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
void
|
|
232
|
+
_TIFFmemcpy(void* d, const void* s, tmsize_t c) {
|
|
233
|
+
memcpy(d, s, (size_t) c);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
int
|
|
237
|
+
_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) {
|
|
238
|
+
return (memcmp(p1, p2, (size_t) c));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ----------------------------------------------------------
|
|
242
|
+
// in FreeImage warnings and errors are disabled
|
|
243
|
+
// ----------------------------------------------------------
|
|
244
|
+
|
|
245
|
+
static void
|
|
246
|
+
msdosWarningHandler(const char* module, const char* fmt, va_list ap) {
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
TIFFErrorHandler _TIFFwarningHandler = msdosWarningHandler;
|
|
250
|
+
|
|
251
|
+
static void
|
|
252
|
+
msdosErrorHandler(const char* module, const char* fmt, va_list ap) {
|
|
253
|
+
|
|
254
|
+
// use this for diagnostic only (do not use otherwise, even in DEBUG mode)
|
|
255
|
+
/*
|
|
256
|
+
if (module != NULL) {
|
|
257
|
+
char msg[1024];
|
|
258
|
+
vsprintf(msg, fmt, ap);
|
|
259
|
+
FreeImage_OutputMessageProc(s_format_id, "%s: %s", module, msg);
|
|
260
|
+
}
|
|
261
|
+
*/
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
TIFFErrorHandler _TIFFerrorHandler = msdosErrorHandler;
|
|
265
|
+
|
|
266
|
+
// ----------------------------------------------------------
|
|
267
|
+
|
|
268
|
+
#define CVT(x) (((x) * 255L) / ((1L<<16)-1))
|
|
269
|
+
#define SCALE(x) (((x)*((1L<<16)-1))/255)
|
|
270
|
+
|
|
271
|
+
// ==========================================================
|
|
272
|
+
// Internal functions
|
|
273
|
+
// ==========================================================
|
|
274
|
+
|
|
275
|
+
static uint16
|
|
276
|
+
CheckColormap(int n, uint16* r, uint16* g, uint16* b) {
|
|
277
|
+
while (n-- > 0) {
|
|
278
|
+
if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) {
|
|
279
|
+
return 16;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return 8;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
Get the TIFFTAG_PHOTOMETRIC value from the dib
|
|
288
|
+
*/
|
|
289
|
+
static uint16
|
|
290
|
+
GetPhotometric(FIBITMAP *dib) {
|
|
291
|
+
FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
|
|
292
|
+
switch(color_type) {
|
|
293
|
+
case FIC_MINISWHITE: // min value is white
|
|
294
|
+
return PHOTOMETRIC_MINISWHITE;
|
|
295
|
+
case FIC_MINISBLACK: // min value is black
|
|
296
|
+
return PHOTOMETRIC_MINISBLACK;
|
|
297
|
+
case FIC_PALETTE: // color map indexed
|
|
298
|
+
return PHOTOMETRIC_PALETTE;
|
|
299
|
+
case FIC_RGB: // RGB color model
|
|
300
|
+
case FIC_RGBALPHA: // RGB color model with alpha channel
|
|
301
|
+
return PHOTOMETRIC_RGB;
|
|
302
|
+
case FIC_CMYK: // CMYK color model
|
|
303
|
+
return PHOTOMETRIC_RGB; // default to RGB unless the save flag is set to TIFF_CMYK
|
|
304
|
+
default:
|
|
305
|
+
return PHOTOMETRIC_MINISBLACK;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
Get the resolution from the TIFF and fill the dib with universal units
|
|
311
|
+
*/
|
|
312
|
+
static void
|
|
313
|
+
ReadResolution(TIFF *tiff, FIBITMAP *dib) {
|
|
314
|
+
float fResX = 300.0;
|
|
315
|
+
float fResY = 300.0;
|
|
316
|
+
uint16 resUnit = RESUNIT_INCH;
|
|
317
|
+
|
|
318
|
+
TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &resUnit);
|
|
319
|
+
TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &fResX);
|
|
320
|
+
TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &fResY);
|
|
321
|
+
|
|
322
|
+
// If we don't have a valid resolution unit and valid resolution is specified then assume inch
|
|
323
|
+
if (resUnit == RESUNIT_NONE && fResX > 0.0 && fResY > 0.0) {
|
|
324
|
+
resUnit = RESUNIT_INCH;
|
|
325
|
+
}
|
|
326
|
+
if (resUnit == RESUNIT_INCH) {
|
|
327
|
+
FreeImage_SetDotsPerMeterX(dib, (unsigned) (fResX/0.0254000 + 0.5));
|
|
328
|
+
FreeImage_SetDotsPerMeterY(dib, (unsigned) (fResY/0.0254000 + 0.5));
|
|
329
|
+
} else if(resUnit == RESUNIT_CENTIMETER) {
|
|
330
|
+
FreeImage_SetDotsPerMeterX(dib, (unsigned) (fResX*100.0 + 0.5));
|
|
331
|
+
FreeImage_SetDotsPerMeterY(dib, (unsigned) (fResY*100.0 + 0.5));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
Set the resolution to the TIFF using english units
|
|
337
|
+
*/
|
|
338
|
+
static void
|
|
339
|
+
WriteResolution(TIFF *tiff, FIBITMAP *dib) {
|
|
340
|
+
double res;
|
|
341
|
+
|
|
342
|
+
TIFFSetField(tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
|
|
343
|
+
|
|
344
|
+
res = (unsigned long) (0.5 + 0.0254 * FreeImage_GetDotsPerMeterX(dib));
|
|
345
|
+
TIFFSetField(tiff, TIFFTAG_XRESOLUTION, res);
|
|
346
|
+
|
|
347
|
+
res = (unsigned long) (0.5 + 0.0254 * FreeImage_GetDotsPerMeterY(dib));
|
|
348
|
+
TIFFSetField(tiff, TIFFTAG_YRESOLUTION, res);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
Fill the dib palette according to the TIFF photometric
|
|
353
|
+
*/
|
|
354
|
+
static void
|
|
355
|
+
ReadPalette(TIFF *tiff, uint16 photometric, uint16 bitspersample, FIBITMAP *dib) {
|
|
356
|
+
RGBQUAD *pal = FreeImage_GetPalette(dib);
|
|
357
|
+
|
|
358
|
+
switch(photometric) {
|
|
359
|
+
case PHOTOMETRIC_MINISBLACK: // bitmap and greyscale image types
|
|
360
|
+
case PHOTOMETRIC_MINISWHITE:
|
|
361
|
+
// Monochrome image
|
|
362
|
+
|
|
363
|
+
if (bitspersample == 1) {
|
|
364
|
+
if (photometric == PHOTOMETRIC_MINISWHITE) {
|
|
365
|
+
pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255;
|
|
366
|
+
pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 0;
|
|
367
|
+
} else {
|
|
368
|
+
pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
|
|
369
|
+
pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
} else if ((bitspersample == 4) ||(bitspersample == 8)) {
|
|
373
|
+
// need to build the scale for greyscale images
|
|
374
|
+
int ncolors = FreeImage_GetColorsUsed(dib);
|
|
375
|
+
|
|
376
|
+
if (photometric == PHOTOMETRIC_MINISBLACK) {
|
|
377
|
+
for (int i = 0; i < ncolors; i++) {
|
|
378
|
+
pal[i].rgbRed =
|
|
379
|
+
pal[i].rgbGreen =
|
|
380
|
+
pal[i].rgbBlue = (BYTE)(i*(255/(ncolors-1)));
|
|
381
|
+
}
|
|
382
|
+
} else {
|
|
383
|
+
for (int i = 0; i < ncolors; i++) {
|
|
384
|
+
pal[i].rgbRed =
|
|
385
|
+
pal[i].rgbGreen =
|
|
386
|
+
pal[i].rgbBlue = (BYTE)(255-i*(255/(ncolors-1)));
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
break;
|
|
392
|
+
|
|
393
|
+
case PHOTOMETRIC_PALETTE: // color map indexed
|
|
394
|
+
uint16 *red;
|
|
395
|
+
uint16 *green;
|
|
396
|
+
uint16 *blue;
|
|
397
|
+
|
|
398
|
+
TIFFGetField(tiff, TIFFTAG_COLORMAP, &red, &green, &blue);
|
|
399
|
+
|
|
400
|
+
// load the palette in the DIB
|
|
401
|
+
|
|
402
|
+
if (CheckColormap(1<<bitspersample, red, green, blue) == 16) {
|
|
403
|
+
for (int i = (1 << bitspersample) - 1; i >= 0; i--) {
|
|
404
|
+
pal[i].rgbRed =(BYTE) CVT(red[i]);
|
|
405
|
+
pal[i].rgbGreen = (BYTE) CVT(green[i]);
|
|
406
|
+
pal[i].rgbBlue = (BYTE) CVT(blue[i]);
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
for (int i = (1 << bitspersample) - 1; i >= 0; i--) {
|
|
410
|
+
pal[i].rgbRed = (BYTE) red[i];
|
|
411
|
+
pal[i].rgbGreen = (BYTE) green[i];
|
|
412
|
+
pal[i].rgbBlue = (BYTE) blue[i];
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
Allocate a FIBITMAP
|
|
422
|
+
@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
|
|
423
|
+
@param fit Image type
|
|
424
|
+
@param width Image width in pixels
|
|
425
|
+
@param height Image height in pixels
|
|
426
|
+
@param bitspersample # bits per sample
|
|
427
|
+
@param samplesperpixel # samples per pixel
|
|
428
|
+
@return Returns the allocated image if successful, returns NULL otherwise
|
|
429
|
+
*/
|
|
430
|
+
static FIBITMAP*
|
|
431
|
+
CreateImageType(BOOL header_only, FREE_IMAGE_TYPE fit, int width, int height, uint16 bitspersample, uint16 samplesperpixel) {
|
|
432
|
+
FIBITMAP *dib = NULL;
|
|
433
|
+
|
|
434
|
+
if((width < 0) || (height < 0)) {
|
|
435
|
+
// check for malicious images
|
|
436
|
+
return NULL;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
int bpp = bitspersample * samplesperpixel;
|
|
440
|
+
|
|
441
|
+
if(fit == FIT_BITMAP) {
|
|
442
|
+
// standard bitmap type
|
|
443
|
+
|
|
444
|
+
if(bpp == 16) {
|
|
445
|
+
|
|
446
|
+
if((samplesperpixel == 2) && (bitspersample == 8)) {
|
|
447
|
+
// 8-bit indexed + 8-bit alpha channel -> convert to 8-bit transparent
|
|
448
|
+
dib = FreeImage_AllocateHeader(header_only, width, height, 8);
|
|
449
|
+
} else {
|
|
450
|
+
// 16-bit RGB -> expect it to be 565
|
|
451
|
+
dib = FreeImage_AllocateHeader(header_only, width, height, bpp, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
|
|
457
|
+
dib = FreeImage_AllocateHeader(header_only, width, height, MIN(bpp, 32), FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
} else {
|
|
462
|
+
// other bitmap types
|
|
463
|
+
|
|
464
|
+
dib = FreeImage_AllocateHeaderT(header_only, fit, width, height, bpp);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return dib;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
Read the TIFFTAG_SAMPLEFORMAT tag and convert to FREE_IMAGE_TYPE
|
|
472
|
+
@param tiff LibTIFF TIFF Handle
|
|
473
|
+
@param bitspersample # bit per sample
|
|
474
|
+
@param samplesperpixel # samples per pixel
|
|
475
|
+
@return Returns the image type as a FREE_IMAGE_TYPE value
|
|
476
|
+
*/
|
|
477
|
+
static FREE_IMAGE_TYPE
|
|
478
|
+
ReadImageType(TIFF *tiff, uint16 bitspersample, uint16 samplesperpixel) {
|
|
479
|
+
uint16 sampleformat = 0;
|
|
480
|
+
FREE_IMAGE_TYPE fit = FIT_BITMAP ;
|
|
481
|
+
|
|
482
|
+
uint16 bpp = bitspersample * samplesperpixel;
|
|
483
|
+
|
|
484
|
+
// try the sampleformat tag
|
|
485
|
+
if(TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleformat)) {
|
|
486
|
+
|
|
487
|
+
switch (sampleformat) {
|
|
488
|
+
case SAMPLEFORMAT_UINT:
|
|
489
|
+
switch (bpp) {
|
|
490
|
+
case 1:
|
|
491
|
+
case 4:
|
|
492
|
+
case 8:
|
|
493
|
+
case 24:
|
|
494
|
+
fit = FIT_BITMAP;
|
|
495
|
+
break;
|
|
496
|
+
case 16:
|
|
497
|
+
// 8-bit + alpha or 16-bit greyscale
|
|
498
|
+
if(samplesperpixel == 2) {
|
|
499
|
+
fit = FIT_BITMAP;
|
|
500
|
+
} else {
|
|
501
|
+
fit = FIT_UINT16;
|
|
502
|
+
}
|
|
503
|
+
break;
|
|
504
|
+
case 32:
|
|
505
|
+
if(samplesperpixel == 4) {
|
|
506
|
+
fit = FIT_BITMAP;
|
|
507
|
+
} else {
|
|
508
|
+
fit = FIT_UINT32;
|
|
509
|
+
}
|
|
510
|
+
break;
|
|
511
|
+
case 48:
|
|
512
|
+
if(samplesperpixel == 3) {
|
|
513
|
+
fit = FIT_RGB16;
|
|
514
|
+
}
|
|
515
|
+
break;
|
|
516
|
+
case 64:
|
|
517
|
+
if(samplesperpixel == 4) {
|
|
518
|
+
fit = FIT_RGBA16;
|
|
519
|
+
}
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
break;
|
|
523
|
+
|
|
524
|
+
case SAMPLEFORMAT_INT:
|
|
525
|
+
switch (bpp) {
|
|
526
|
+
case 16:
|
|
527
|
+
if(samplesperpixel == 3) {
|
|
528
|
+
fit = FIT_BITMAP;
|
|
529
|
+
} else {
|
|
530
|
+
fit = FIT_INT16;
|
|
531
|
+
}
|
|
532
|
+
break;
|
|
533
|
+
case 32:
|
|
534
|
+
fit = FIT_INT32;
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
break;
|
|
538
|
+
|
|
539
|
+
case SAMPLEFORMAT_IEEEFP:
|
|
540
|
+
switch (bpp) {
|
|
541
|
+
case 32:
|
|
542
|
+
fit = FIT_FLOAT;
|
|
543
|
+
break;
|
|
544
|
+
case 48:
|
|
545
|
+
// 3 x half float => convert to RGBF
|
|
546
|
+
if((samplesperpixel == 3) && (bitspersample == 16)) {
|
|
547
|
+
fit = FIT_RGBF;
|
|
548
|
+
}
|
|
549
|
+
break;
|
|
550
|
+
case 64:
|
|
551
|
+
if(samplesperpixel == 2) {
|
|
552
|
+
fit = FIT_FLOAT;
|
|
553
|
+
} else {
|
|
554
|
+
fit = FIT_DOUBLE;
|
|
555
|
+
}
|
|
556
|
+
break;
|
|
557
|
+
case 96:
|
|
558
|
+
fit = FIT_RGBF;
|
|
559
|
+
break;
|
|
560
|
+
default:
|
|
561
|
+
if(bpp >= 128) {
|
|
562
|
+
fit = FIT_RGBAF;
|
|
563
|
+
}
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
break;
|
|
567
|
+
case SAMPLEFORMAT_COMPLEXIEEEFP:
|
|
568
|
+
switch (bpp) {
|
|
569
|
+
case 64:
|
|
570
|
+
break;
|
|
571
|
+
case 128:
|
|
572
|
+
fit = FIT_COMPLEX;
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
break;
|
|
576
|
+
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
// no sampleformat tag : assume SAMPLEFORMAT_UINT
|
|
580
|
+
else {
|
|
581
|
+
if(samplesperpixel == 1) {
|
|
582
|
+
switch (bpp) {
|
|
583
|
+
case 16:
|
|
584
|
+
fit = FIT_UINT16;
|
|
585
|
+
break;
|
|
586
|
+
|
|
587
|
+
case 32:
|
|
588
|
+
fit = FIT_UINT32;
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
else if(samplesperpixel == 3) {
|
|
593
|
+
if(bpp == 48) fit = FIT_RGB16;
|
|
594
|
+
}
|
|
595
|
+
else if(samplesperpixel >= 4) {
|
|
596
|
+
if(bitspersample == 16) {
|
|
597
|
+
fit = FIT_RGBA16;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return fit;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
Convert FREE_IMAGE_TYPE and write TIFFTAG_SAMPLEFORMAT
|
|
608
|
+
@param tiff LibTIFF TIFF Handle
|
|
609
|
+
@param fit Image type as a FREE_IMAGE_TYPE value
|
|
610
|
+
*/
|
|
611
|
+
static void
|
|
612
|
+
WriteImageType(TIFF *tiff, FREE_IMAGE_TYPE fit) {
|
|
613
|
+
switch(fit) {
|
|
614
|
+
case FIT_BITMAP: // standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
|
|
615
|
+
case FIT_UINT16: // array of unsigned short : unsigned 16-bit
|
|
616
|
+
case FIT_UINT32: // array of unsigned long : unsigned 32-bit
|
|
617
|
+
case FIT_RGB16: // 48-bit RGB image : 3 x 16-bit
|
|
618
|
+
case FIT_RGBA16: // 64-bit RGBA image : 4 x 16-bit
|
|
619
|
+
TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
|
620
|
+
break;
|
|
621
|
+
|
|
622
|
+
case FIT_INT16: // array of short : signed 16-bit
|
|
623
|
+
case FIT_INT32: // array of long : signed 32-bit
|
|
624
|
+
TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
|
|
625
|
+
break;
|
|
626
|
+
|
|
627
|
+
case FIT_FLOAT: // array of float : 32-bit
|
|
628
|
+
case FIT_DOUBLE: // array of double : 64-bit
|
|
629
|
+
case FIT_RGBF: // 96-bit RGB float image : 3 x 32-bit IEEE floating point
|
|
630
|
+
case FIT_RGBAF: // 128-bit RGBA float image : 4 x 32-bit IEEE floating point
|
|
631
|
+
TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
|
|
632
|
+
break;
|
|
633
|
+
|
|
634
|
+
case FIT_COMPLEX: // array of COMPLEX : 2 x 64-bit
|
|
635
|
+
TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_COMPLEXIEEEFP);
|
|
636
|
+
break;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
Select the compression algorithm
|
|
642
|
+
@param tiff LibTIFF TIFF Handle
|
|
643
|
+
@param
|
|
644
|
+
*/
|
|
645
|
+
static void
|
|
646
|
+
WriteCompression(TIFF *tiff, uint16 bitspersample, uint16 samplesperpixel, uint16 photometric, int flags) {
|
|
647
|
+
uint16 compression;
|
|
648
|
+
uint16 bitsperpixel = bitspersample * samplesperpixel;
|
|
649
|
+
|
|
650
|
+
if(photometric == PHOTOMETRIC_LOGLUV) {
|
|
651
|
+
compression = COMPRESSION_SGILOG;
|
|
652
|
+
} else if ((flags & TIFF_PACKBITS) == TIFF_PACKBITS) {
|
|
653
|
+
compression = COMPRESSION_PACKBITS;
|
|
654
|
+
} else if ((flags & TIFF_DEFLATE) == TIFF_DEFLATE) {
|
|
655
|
+
compression = COMPRESSION_DEFLATE;
|
|
656
|
+
} else if ((flags & TIFF_ADOBE_DEFLATE) == TIFF_ADOBE_DEFLATE) {
|
|
657
|
+
compression = COMPRESSION_ADOBE_DEFLATE;
|
|
658
|
+
} else if ((flags & TIFF_NONE) == TIFF_NONE) {
|
|
659
|
+
compression = COMPRESSION_NONE;
|
|
660
|
+
} else if ((bitsperpixel == 1) && ((flags & TIFF_CCITTFAX3) == TIFF_CCITTFAX3)) {
|
|
661
|
+
compression = COMPRESSION_CCITTFAX3;
|
|
662
|
+
} else if ((bitsperpixel == 1) && ((flags & TIFF_CCITTFAX4) == TIFF_CCITTFAX4)) {
|
|
663
|
+
compression = COMPRESSION_CCITTFAX4;
|
|
664
|
+
} else if ((flags & TIFF_LZW) == TIFF_LZW) {
|
|
665
|
+
compression = COMPRESSION_LZW;
|
|
666
|
+
} else if ((flags & TIFF_JPEG) == TIFF_JPEG) {
|
|
667
|
+
if(((bitsperpixel == 8) && (photometric != PHOTOMETRIC_PALETTE)) || (bitsperpixel == 24)) {
|
|
668
|
+
compression = COMPRESSION_JPEG;
|
|
669
|
+
// RowsPerStrip must be multiple of 8 for JPEG
|
|
670
|
+
uint32 rowsperstrip = (uint32) -1;
|
|
671
|
+
rowsperstrip = TIFFDefaultStripSize(tiff, rowsperstrip);
|
|
672
|
+
rowsperstrip = rowsperstrip + (8 - (rowsperstrip % 8));
|
|
673
|
+
// overwrite previous RowsPerStrip
|
|
674
|
+
TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
|
|
675
|
+
} else {
|
|
676
|
+
// default to LZW
|
|
677
|
+
compression = COMPRESSION_LZW;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
// default compression scheme
|
|
682
|
+
|
|
683
|
+
switch(bitsperpixel) {
|
|
684
|
+
case 1:
|
|
685
|
+
compression = COMPRESSION_CCITTFAX4;
|
|
686
|
+
break;
|
|
687
|
+
|
|
688
|
+
case 4:
|
|
689
|
+
case 8:
|
|
690
|
+
case 16:
|
|
691
|
+
case 24:
|
|
692
|
+
case 32:
|
|
693
|
+
compression = COMPRESSION_LZW;
|
|
694
|
+
break;
|
|
695
|
+
case 48:
|
|
696
|
+
case 64:
|
|
697
|
+
case 96:
|
|
698
|
+
case 128:
|
|
699
|
+
compression = COMPRESSION_LZW;
|
|
700
|
+
break;
|
|
701
|
+
|
|
702
|
+
default :
|
|
703
|
+
compression = COMPRESSION_NONE;
|
|
704
|
+
break;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
TIFFSetField(tiff, TIFFTAG_COMPRESSION, compression);
|
|
709
|
+
|
|
710
|
+
if(compression == COMPRESSION_LZW) {
|
|
711
|
+
// This option is only meaningful with LZW compression: a predictor value of 2
|
|
712
|
+
// causes each scanline of the output image to undergo horizontal differencing
|
|
713
|
+
// before it is encoded; a value of 1 forces each scanline to be encoded without differencing.
|
|
714
|
+
|
|
715
|
+
// Found on LibTIFF mailing list :
|
|
716
|
+
// LZW without differencing works well for 1-bit images, 4-bit grayscale images,
|
|
717
|
+
// and many palette-color images. But natural 24-bit color images and some 8-bit
|
|
718
|
+
// grayscale images do much better with differencing.
|
|
719
|
+
|
|
720
|
+
if((bitspersample == 8) || (bitspersample == 16)) {
|
|
721
|
+
if ((bitsperpixel >= 8) && (photometric != PHOTOMETRIC_PALETTE)) {
|
|
722
|
+
TIFFSetField(tiff, TIFFTAG_PREDICTOR, 2);
|
|
723
|
+
} else {
|
|
724
|
+
TIFFSetField(tiff, TIFFTAG_PREDICTOR, 1);
|
|
725
|
+
}
|
|
726
|
+
} else {
|
|
727
|
+
TIFFSetField(tiff, TIFFTAG_PREDICTOR, 1);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
else if((compression == COMPRESSION_CCITTFAX3) || (compression == COMPRESSION_CCITTFAX4)) {
|
|
731
|
+
uint32 imageLength = 0;
|
|
732
|
+
TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &imageLength);
|
|
733
|
+
// overwrite previous RowsPerStrip
|
|
734
|
+
TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, imageLength);
|
|
735
|
+
|
|
736
|
+
if(compression == COMPRESSION_CCITTFAX3) {
|
|
737
|
+
// try to be compliant with the TIFF Class F specification
|
|
738
|
+
// that documents the TIFF tags specific to FAX applications
|
|
739
|
+
// see http://palimpsest.stanford.edu/bytopic/imaging/std/tiff-f.html
|
|
740
|
+
uint32 group3options = GROUP3OPT_2DENCODING | GROUP3OPT_FILLBITS;
|
|
741
|
+
TIFFSetField(tiff, TIFFTAG_GROUP3OPTIONS, group3options); // 2d-encoded, has aligned EOL
|
|
742
|
+
TIFFSetField(tiff, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB); // lsb-to-msb fillorder
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// ==========================================================
|
|
748
|
+
// TIFF metadata routines
|
|
749
|
+
// ==========================================================
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
Read the TIFFTAG_RICHTIFFIPTC tag (IPTC/NAA or Adobe Photoshop profile)
|
|
753
|
+
*/
|
|
754
|
+
static BOOL
|
|
755
|
+
tiff_read_iptc_profile(TIFF *tiff, FIBITMAP *dib) {
|
|
756
|
+
BYTE *profile = NULL;
|
|
757
|
+
uint32 profile_size = 0;
|
|
758
|
+
|
|
759
|
+
if(TIFFGetField(tiff,TIFFTAG_RICHTIFFIPTC, &profile_size, &profile) == 1) {
|
|
760
|
+
if (TIFFIsByteSwapped(tiff) != 0) {
|
|
761
|
+
TIFFSwabArrayOfLong((uint32 *) profile, (unsigned long)profile_size);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
return read_iptc_profile(dib, profile, 4 * profile_size);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
return FALSE;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
Read the TIFFTAG_XMLPACKET tag (XMP profile)
|
|
772
|
+
@param dib Input FIBITMAP
|
|
773
|
+
@param tiff LibTIFF TIFF handle
|
|
774
|
+
@return Returns TRUE if successful, FALSE otherwise
|
|
775
|
+
*/
|
|
776
|
+
static BOOL
|
|
777
|
+
tiff_read_xmp_profile(TIFF *tiff, FIBITMAP *dib) {
|
|
778
|
+
BYTE *profile = NULL;
|
|
779
|
+
uint32 profile_size = 0;
|
|
780
|
+
|
|
781
|
+
if (TIFFGetField(tiff, TIFFTAG_XMLPACKET, &profile_size, &profile) == 1) {
|
|
782
|
+
// create a tag
|
|
783
|
+
FITAG *tag = FreeImage_CreateTag();
|
|
784
|
+
if(!tag) return FALSE;
|
|
785
|
+
|
|
786
|
+
FreeImage_SetTagID(tag, TIFFTAG_XMLPACKET); // 700
|
|
787
|
+
FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
|
|
788
|
+
FreeImage_SetTagLength(tag, profile_size);
|
|
789
|
+
FreeImage_SetTagCount(tag, profile_size);
|
|
790
|
+
FreeImage_SetTagType(tag, FIDT_ASCII);
|
|
791
|
+
FreeImage_SetTagValue(tag, profile);
|
|
792
|
+
|
|
793
|
+
// store the tag
|
|
794
|
+
FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);
|
|
795
|
+
|
|
796
|
+
// destroy the tag
|
|
797
|
+
FreeImage_DeleteTag(tag);
|
|
798
|
+
|
|
799
|
+
return TRUE;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
return FALSE;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
Read the Exif profile embedded in a TIFF
|
|
807
|
+
@param dib Input FIBITMAP
|
|
808
|
+
@param tiff LibTIFF TIFF handle
|
|
809
|
+
@return Returns TRUE if successful, FALSE otherwise
|
|
810
|
+
*/
|
|
811
|
+
static BOOL
|
|
812
|
+
tiff_read_exif_profile(TIFF *tiff, FIBITMAP *dib) {
|
|
813
|
+
BOOL bResult = FALSE;
|
|
814
|
+
toff_t exif_offset = 0;
|
|
815
|
+
|
|
816
|
+
// read EXIF-TIFF tags
|
|
817
|
+
bResult = tiff_read_exif_tags(tiff, TagLib::EXIF_MAIN, dib);
|
|
818
|
+
|
|
819
|
+
// get the IFD offset
|
|
820
|
+
if(TIFFGetField(tiff, TIFFTAG_EXIFIFD, &exif_offset)) {
|
|
821
|
+
|
|
822
|
+
// read EXIF tags
|
|
823
|
+
if(!TIFFReadEXIFDirectory(tiff, exif_offset)) {
|
|
824
|
+
return FALSE;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// read all known exif tags
|
|
828
|
+
bResult = tiff_read_exif_tags(tiff, TagLib::EXIF_EXIF, dib);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
return bResult;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
Read TIFF special profiles
|
|
836
|
+
*/
|
|
837
|
+
static void
|
|
838
|
+
ReadMetadata(TIFF *tiff, FIBITMAP *dib) {
|
|
839
|
+
|
|
840
|
+
// IPTC/NAA
|
|
841
|
+
tiff_read_iptc_profile(tiff, dib);
|
|
842
|
+
|
|
843
|
+
// Adobe XMP
|
|
844
|
+
tiff_read_xmp_profile(tiff, dib);
|
|
845
|
+
|
|
846
|
+
// GeoTIFF
|
|
847
|
+
tiff_read_geotiff_profile(tiff, dib);
|
|
848
|
+
|
|
849
|
+
// Exif-TIFF
|
|
850
|
+
tiff_read_exif_profile(tiff, dib);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// ----------------------------------------------------------
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
Write the TIFFTAG_RICHTIFFIPTC tag (IPTC/NAA or Adobe Photoshop profile)
|
|
857
|
+
*/
|
|
858
|
+
static BOOL
|
|
859
|
+
tiff_write_iptc_profile(TIFF *tiff, FIBITMAP *dib) {
|
|
860
|
+
if(FreeImage_GetMetadataCount(FIMD_IPTC, dib)) {
|
|
861
|
+
BYTE *profile = NULL;
|
|
862
|
+
uint32 profile_size = 0;
|
|
863
|
+
// create a binary profile
|
|
864
|
+
if(write_iptc_profile(dib, &profile, &profile_size)) {
|
|
865
|
+
uint32 iptc_size = profile_size;
|
|
866
|
+
iptc_size += (4-(iptc_size & 0x03)); // Round up for long word alignment
|
|
867
|
+
BYTE *iptc_profile = (BYTE*)malloc(iptc_size);
|
|
868
|
+
if(!iptc_profile) {
|
|
869
|
+
free(profile);
|
|
870
|
+
return FALSE;
|
|
871
|
+
}
|
|
872
|
+
memset(iptc_profile, 0, iptc_size);
|
|
873
|
+
memcpy(iptc_profile, profile, profile_size);
|
|
874
|
+
if (TIFFIsByteSwapped(tiff)) {
|
|
875
|
+
TIFFSwabArrayOfLong((uint32 *) iptc_profile, (unsigned long)iptc_size/4);
|
|
876
|
+
}
|
|
877
|
+
// Tag is type TIFF_LONG so byte length is divided by four
|
|
878
|
+
TIFFSetField(tiff, TIFFTAG_RICHTIFFIPTC, iptc_size/4, iptc_profile);
|
|
879
|
+
// release the profile data
|
|
880
|
+
free(iptc_profile);
|
|
881
|
+
free(profile);
|
|
882
|
+
|
|
883
|
+
return TRUE;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
return FALSE;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
Write the TIFFTAG_XMLPACKET tag (XMP profile)
|
|
892
|
+
@param dib Input FIBITMAP
|
|
893
|
+
@param tiff LibTIFF TIFF handle
|
|
894
|
+
@return Returns TRUE if successful, FALSE otherwise
|
|
895
|
+
*/
|
|
896
|
+
static BOOL
|
|
897
|
+
tiff_write_xmp_profile(TIFF *tiff, FIBITMAP *dib) {
|
|
898
|
+
FITAG *tag_xmp = NULL;
|
|
899
|
+
FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag_xmp);
|
|
900
|
+
|
|
901
|
+
if(tag_xmp && (NULL != FreeImage_GetTagValue(tag_xmp))) {
|
|
902
|
+
|
|
903
|
+
TIFFSetField(tiff, TIFFTAG_XMLPACKET, (uint32)FreeImage_GetTagLength(tag_xmp), (BYTE*)FreeImage_GetTagValue(tag_xmp));
|
|
904
|
+
|
|
905
|
+
return TRUE;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
return FALSE;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
Write the Exif profile to TIFF
|
|
913
|
+
@param dib Input FIBITMAP
|
|
914
|
+
@param tiff LibTIFF TIFF handle
|
|
915
|
+
@return Returns TRUE if successful, FALSE otherwise
|
|
916
|
+
*/
|
|
917
|
+
static BOOL
|
|
918
|
+
tiff_write_exif_profile(TIFF *tiff, FIBITMAP *dib) {
|
|
919
|
+
BOOL bResult = FALSE;
|
|
920
|
+
|
|
921
|
+
// write EXIF_MAIN tags, EXIF_EXIF not supported yet
|
|
922
|
+
bResult = tiff_write_exif_tags(tiff, TagLib::EXIF_MAIN, dib);
|
|
923
|
+
|
|
924
|
+
return bResult;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
Write TIFF special profiles
|
|
929
|
+
*/
|
|
930
|
+
static void
|
|
931
|
+
WriteMetadata(TIFF *tiff, FIBITMAP *dib) {
|
|
932
|
+
// IPTC
|
|
933
|
+
tiff_write_iptc_profile(tiff, dib);
|
|
934
|
+
|
|
935
|
+
// Adobe XMP
|
|
936
|
+
tiff_write_xmp_profile(tiff, dib);
|
|
937
|
+
|
|
938
|
+
// EXIF_MAIN tags
|
|
939
|
+
tiff_write_exif_profile(tiff, dib);
|
|
940
|
+
|
|
941
|
+
// GeoTIFF tags
|
|
942
|
+
tiff_write_geotiff_profile(tiff, dib);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// ==========================================================
|
|
946
|
+
// Plugin Implementation
|
|
947
|
+
// ==========================================================
|
|
948
|
+
|
|
949
|
+
static const char * DLL_CALLCONV
|
|
950
|
+
Format() {
|
|
951
|
+
return "TIFF";
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
static const char * DLL_CALLCONV
|
|
955
|
+
Description() {
|
|
956
|
+
return "Tagged Image File Format";
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
static const char * DLL_CALLCONV
|
|
960
|
+
Extension() {
|
|
961
|
+
return "tif,tiff";
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
static const char * DLL_CALLCONV
|
|
965
|
+
RegExpr() {
|
|
966
|
+
return "^[MI][MI][\\x01*][\\x01*]";
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
static const char * DLL_CALLCONV
|
|
970
|
+
MimeType() {
|
|
971
|
+
return "image/tiff";
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
static BOOL DLL_CALLCONV
|
|
975
|
+
Validate(FreeImageIO *io, fi_handle handle) {
|
|
976
|
+
BYTE tiff_id1[] = { 0x49, 0x49, 0x2A, 0x00 }; // Classic TIFF, little-endian
|
|
977
|
+
BYTE tiff_id2[] = { 0x4D, 0x4D, 0x00, 0x2A }; // Classic TIFF, big-endian
|
|
978
|
+
BYTE tiff_id3[] = { 0x49, 0x49, 0x2B, 0x00 }; // Big TIFF, little-endian
|
|
979
|
+
BYTE tiff_id4[] = { 0x4D, 0x4D, 0x00, 0x2B }; // Big TIFF, big-endian
|
|
980
|
+
BYTE signature[4] = { 0, 0, 0, 0 };
|
|
981
|
+
|
|
982
|
+
io->read_proc(signature, 1, 4, handle);
|
|
983
|
+
|
|
984
|
+
if(memcmp(tiff_id1, signature, 4) == 0)
|
|
985
|
+
return TRUE;
|
|
986
|
+
if(memcmp(tiff_id2, signature, 4) == 0)
|
|
987
|
+
return TRUE;
|
|
988
|
+
if(memcmp(tiff_id3, signature, 4) == 0)
|
|
989
|
+
return TRUE;
|
|
990
|
+
if(memcmp(tiff_id4, signature, 4) == 0)
|
|
991
|
+
return TRUE;
|
|
992
|
+
|
|
993
|
+
return FALSE;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
static BOOL DLL_CALLCONV
|
|
997
|
+
SupportsExportDepth(int depth) {
|
|
998
|
+
return (
|
|
999
|
+
(depth == 1) ||
|
|
1000
|
+
(depth == 4) ||
|
|
1001
|
+
(depth == 8) ||
|
|
1002
|
+
(depth == 24) ||
|
|
1003
|
+
(depth == 32)
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
static BOOL DLL_CALLCONV
|
|
1008
|
+
SupportsExportType(FREE_IMAGE_TYPE type) {
|
|
1009
|
+
return (
|
|
1010
|
+
(type == FIT_BITMAP) ||
|
|
1011
|
+
(type == FIT_UINT16) ||
|
|
1012
|
+
(type == FIT_INT16) ||
|
|
1013
|
+
(type == FIT_UINT32) ||
|
|
1014
|
+
(type == FIT_INT32) ||
|
|
1015
|
+
(type == FIT_FLOAT) ||
|
|
1016
|
+
(type == FIT_DOUBLE) ||
|
|
1017
|
+
(type == FIT_COMPLEX) ||
|
|
1018
|
+
(type == FIT_RGB16) ||
|
|
1019
|
+
(type == FIT_RGBA16) ||
|
|
1020
|
+
(type == FIT_RGBF) ||
|
|
1021
|
+
(type == FIT_RGBAF)
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
static BOOL DLL_CALLCONV
|
|
1026
|
+
SupportsICCProfiles() {
|
|
1027
|
+
return TRUE;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
static BOOL DLL_CALLCONV
|
|
1031
|
+
SupportsNoPixels() {
|
|
1032
|
+
return TRUE;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
// ----------------------------------------------------------
|
|
1036
|
+
|
|
1037
|
+
static void * DLL_CALLCONV
|
|
1038
|
+
Open(FreeImageIO *io, fi_handle handle, BOOL read) {
|
|
1039
|
+
// wrapper for TIFF I/O
|
|
1040
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)malloc(sizeof(fi_TIFFIO));
|
|
1041
|
+
if(!fio) return NULL;
|
|
1042
|
+
fio->io = io;
|
|
1043
|
+
fio->handle = handle;
|
|
1044
|
+
|
|
1045
|
+
if (read) {
|
|
1046
|
+
fio->tif = TIFFFdOpen((thandle_t)fio, "", "r");
|
|
1047
|
+
} else {
|
|
1048
|
+
// mode = "w" : write Classic TIFF
|
|
1049
|
+
// mode = "w8" : write Big TIFF
|
|
1050
|
+
fio->tif = TIFFFdOpen((thandle_t)fio, "", "w");
|
|
1051
|
+
}
|
|
1052
|
+
if(fio->tif == NULL) {
|
|
1053
|
+
free(fio);
|
|
1054
|
+
FreeImage_OutputMessageProc(s_format_id, "Error while opening TIFF: data is invalid");
|
|
1055
|
+
return NULL;
|
|
1056
|
+
}
|
|
1057
|
+
return fio;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
static void DLL_CALLCONV
|
|
1061
|
+
Close(FreeImageIO *io, fi_handle handle, void *data) {
|
|
1062
|
+
if(data) {
|
|
1063
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)data;
|
|
1064
|
+
TIFFClose(fio->tif);
|
|
1065
|
+
free(fio);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
// ----------------------------------------------------------
|
|
1070
|
+
|
|
1071
|
+
static int DLL_CALLCONV
|
|
1072
|
+
PageCount(FreeImageIO *io, fi_handle handle, void *data) {
|
|
1073
|
+
if(data) {
|
|
1074
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)data;
|
|
1075
|
+
TIFF *tif = (TIFF *)fio->tif;
|
|
1076
|
+
int nr_ifd = 0;
|
|
1077
|
+
|
|
1078
|
+
do {
|
|
1079
|
+
nr_ifd++;
|
|
1080
|
+
} while (TIFFReadDirectory(tif));
|
|
1081
|
+
|
|
1082
|
+
return nr_ifd;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
return 0;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// ----------------------------------------------------------
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
check for uncommon bitspersample values (e.g. 10, 12, ...)
|
|
1092
|
+
@param photometric TIFFTAG_PHOTOMETRIC tiff tag
|
|
1093
|
+
@param bitspersample TIFFTAG_BITSPERSAMPLE tiff tag
|
|
1094
|
+
@return Returns FALSE if a uncommon bit-depth is encountered, returns TRUE otherwise
|
|
1095
|
+
*/
|
|
1096
|
+
static BOOL
|
|
1097
|
+
IsValidBitsPerSample(uint16 photometric, uint16 bitspersample) {
|
|
1098
|
+
|
|
1099
|
+
switch(bitspersample) {
|
|
1100
|
+
case 1:
|
|
1101
|
+
case 4:
|
|
1102
|
+
if((photometric == PHOTOMETRIC_MINISWHITE) || (photometric == PHOTOMETRIC_MINISBLACK) || (photometric == PHOTOMETRIC_PALETTE)) {
|
|
1103
|
+
return TRUE;
|
|
1104
|
+
} else {
|
|
1105
|
+
return FALSE;
|
|
1106
|
+
}
|
|
1107
|
+
break;
|
|
1108
|
+
case 8:
|
|
1109
|
+
return TRUE;
|
|
1110
|
+
case 16:
|
|
1111
|
+
if(photometric != PHOTOMETRIC_PALETTE) {
|
|
1112
|
+
return TRUE;
|
|
1113
|
+
} else {
|
|
1114
|
+
return FALSE;
|
|
1115
|
+
}
|
|
1116
|
+
break;
|
|
1117
|
+
case 32:
|
|
1118
|
+
if((photometric == PHOTOMETRIC_MINISWHITE) || (photometric == PHOTOMETRIC_MINISBLACK) || (photometric == PHOTOMETRIC_LOGLUV)) {
|
|
1119
|
+
return TRUE;
|
|
1120
|
+
} else {
|
|
1121
|
+
return FALSE;
|
|
1122
|
+
}
|
|
1123
|
+
break;
|
|
1124
|
+
case 64:
|
|
1125
|
+
case 128:
|
|
1126
|
+
if(photometric == PHOTOMETRIC_MINISBLACK) {
|
|
1127
|
+
return TRUE;
|
|
1128
|
+
} else {
|
|
1129
|
+
return FALSE;
|
|
1130
|
+
}
|
|
1131
|
+
break;
|
|
1132
|
+
default:
|
|
1133
|
+
return FALSE;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
static TIFFLoadMethod
|
|
1138
|
+
FindLoadMethod(TIFF *tif, FREE_IMAGE_TYPE image_type, int flags) {
|
|
1139
|
+
uint16 bitspersample = (uint16)-1;
|
|
1140
|
+
uint16 samplesperpixel = (uint16)-1;
|
|
1141
|
+
uint16 photometric = (uint16)-1;
|
|
1142
|
+
uint16 planar_config = (uint16)-1;
|
|
1143
|
+
|
|
1144
|
+
TIFFLoadMethod loadMethod = LoadAsGenericStrip;
|
|
1145
|
+
|
|
1146
|
+
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
|
|
1147
|
+
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
|
|
1148
|
+
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
|
|
1149
|
+
TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
|
|
1150
|
+
|
|
1151
|
+
BOOL bIsTiled = (TIFFIsTiled(tif) == 0) ? FALSE:TRUE;
|
|
1152
|
+
|
|
1153
|
+
switch(photometric) {
|
|
1154
|
+
// convert to 24 or 32 bits RGB if the image is full color
|
|
1155
|
+
case PHOTOMETRIC_RGB:
|
|
1156
|
+
if((image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) {
|
|
1157
|
+
// load 48-bit RGB and 64-bit RGBA without conversion
|
|
1158
|
+
loadMethod = LoadAsGenericStrip;
|
|
1159
|
+
}
|
|
1160
|
+
else if(image_type == FIT_RGBF) {
|
|
1161
|
+
if((samplesperpixel == 3) && (bitspersample == 16)) {
|
|
1162
|
+
// load 3 x 16-bit half as RGBF
|
|
1163
|
+
loadMethod = LoadAsHalfFloat;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
break;
|
|
1167
|
+
case PHOTOMETRIC_YCBCR:
|
|
1168
|
+
case PHOTOMETRIC_CIELAB:
|
|
1169
|
+
case PHOTOMETRIC_ICCLAB:
|
|
1170
|
+
case PHOTOMETRIC_ITULAB:
|
|
1171
|
+
loadMethod = LoadAsRBGA;
|
|
1172
|
+
break;
|
|
1173
|
+
case PHOTOMETRIC_LOGLUV:
|
|
1174
|
+
loadMethod = LoadAsLogLuv;
|
|
1175
|
+
break;
|
|
1176
|
+
case PHOTOMETRIC_SEPARATED:
|
|
1177
|
+
// if image is PHOTOMETRIC_SEPARATED _and_ comes with an ICC profile,
|
|
1178
|
+
// then the image should preserve its original (CMYK) colour model and
|
|
1179
|
+
// should be read as CMYK (to keep the match of pixel and profile and
|
|
1180
|
+
// to avoid multiple conversions. Conversion can be done by changing
|
|
1181
|
+
// the profile from it's original CMYK to an RGB profile with an
|
|
1182
|
+
// apropriate color management system. Works with non-tiled TIFFs.
|
|
1183
|
+
if(!bIsTiled) {
|
|
1184
|
+
loadMethod = LoadAsCMYK;
|
|
1185
|
+
}
|
|
1186
|
+
break;
|
|
1187
|
+
case PHOTOMETRIC_MINISWHITE:
|
|
1188
|
+
case PHOTOMETRIC_MINISBLACK:
|
|
1189
|
+
case PHOTOMETRIC_PALETTE:
|
|
1190
|
+
// When samplesperpixel = 2 and bitspersample = 8, set the image as a
|
|
1191
|
+
// 8-bit indexed image + 8-bit alpha layer image
|
|
1192
|
+
// and convert to a 8-bit image with a transparency table
|
|
1193
|
+
if((samplesperpixel > 1) && (bitspersample == 8)) {
|
|
1194
|
+
loadMethod = LoadAs8BitTrns;
|
|
1195
|
+
} else {
|
|
1196
|
+
loadMethod = LoadAsGenericStrip;
|
|
1197
|
+
}
|
|
1198
|
+
break;
|
|
1199
|
+
default:
|
|
1200
|
+
loadMethod = LoadAsGenericStrip;
|
|
1201
|
+
break;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
if((loadMethod == LoadAsGenericStrip) && bIsTiled) {
|
|
1205
|
+
loadMethod = LoadAsTiled;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
return loadMethod;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
// ==========================================================
|
|
1212
|
+
// TIFF thumbnail routines
|
|
1213
|
+
// ==========================================================
|
|
1214
|
+
|
|
1215
|
+
static FIBITMAP * DLL_CALLCONV
|
|
1216
|
+
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data);
|
|
1217
|
+
|
|
1218
|
+
/**
|
|
1219
|
+
Read embedded thumbnail
|
|
1220
|
+
*/
|
|
1221
|
+
static void
|
|
1222
|
+
ReadThumbnail(FreeImageIO *io, fi_handle handle, void *data, TIFF *tiff, FIBITMAP *dib) {
|
|
1223
|
+
FIBITMAP* thumbnail = NULL;
|
|
1224
|
+
|
|
1225
|
+
// read exif thumbnail (IFD 1) ...
|
|
1226
|
+
|
|
1227
|
+
uint32 exif_offset = 0;
|
|
1228
|
+
if(TIFFGetField(tiff, TIFFTAG_EXIFIFD, &exif_offset)) {
|
|
1229
|
+
|
|
1230
|
+
if(TIFFLastDirectory(tiff) != 0) {
|
|
1231
|
+
// save current position
|
|
1232
|
+
long tell_pos = io->tell_proc(handle);
|
|
1233
|
+
uint16 cur_dir = TIFFCurrentDirectory(tiff);
|
|
1234
|
+
|
|
1235
|
+
// load the thumbnail
|
|
1236
|
+
int page = 1;
|
|
1237
|
+
int flags = TIFF_DEFAULT;
|
|
1238
|
+
thumbnail = Load(io, handle, page, flags, data);
|
|
1239
|
+
// store the thumbnail (remember to release it later ...)
|
|
1240
|
+
FreeImage_SetThumbnail(dib, thumbnail);
|
|
1241
|
+
|
|
1242
|
+
// restore current position
|
|
1243
|
+
io->seek_proc(handle, tell_pos, SEEK_SET);
|
|
1244
|
+
TIFFSetDirectory(tiff, cur_dir);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
// ... or read the first subIFD
|
|
1249
|
+
|
|
1250
|
+
if(!thumbnail) {
|
|
1251
|
+
uint16 subIFD_count = 0;
|
|
1252
|
+
uint64* subIFD_offsets = NULL;
|
|
1253
|
+
// ### Theoretically this should also read the first subIFD from a Photoshop-created file with "pyramid".
|
|
1254
|
+
// It does not however - the tag is there (using Tag Viewer app) but libtiff refuses to read it
|
|
1255
|
+
if(TIFFGetField(tiff, TIFFTAG_SUBIFD, &subIFD_count, &subIFD_offsets)) {
|
|
1256
|
+
if(subIFD_count > 0) {
|
|
1257
|
+
// save current position
|
|
1258
|
+
long tell_pos = io->tell_proc(handle);
|
|
1259
|
+
uint16 cur_dir = TIFFCurrentDirectory(tiff);
|
|
1260
|
+
if(TIFFSetSubDirectory(tiff, subIFD_offsets[0])) {
|
|
1261
|
+
// load the thumbnail
|
|
1262
|
+
int page = -1;
|
|
1263
|
+
int flags = TIFF_DEFAULT;
|
|
1264
|
+
thumbnail = Load(io, handle, page, flags, data);
|
|
1265
|
+
// store the thumbnail (remember to release it later ...)
|
|
1266
|
+
FreeImage_SetThumbnail(dib, thumbnail);
|
|
1267
|
+
}
|
|
1268
|
+
// restore current position
|
|
1269
|
+
io->seek_proc(handle, tell_pos, SEEK_SET);
|
|
1270
|
+
TIFFSetDirectory(tiff, cur_dir);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
// ... or read Photoshop thumbnail
|
|
1276
|
+
|
|
1277
|
+
if(!thumbnail) {
|
|
1278
|
+
uint32 ps_size = 0;
|
|
1279
|
+
void *ps_data = NULL;
|
|
1280
|
+
|
|
1281
|
+
if(TIFFGetField(tiff, TIFFTAG_PHOTOSHOP, &ps_size, &ps_data)) {
|
|
1282
|
+
FIMEMORY *handle = FreeImage_OpenMemory((BYTE*)ps_data, ps_size);
|
|
1283
|
+
|
|
1284
|
+
FreeImageIO io;
|
|
1285
|
+
SetMemoryIO(&io);
|
|
1286
|
+
|
|
1287
|
+
psdParser parser;
|
|
1288
|
+
parser.ReadImageResources(&io, handle, ps_size);
|
|
1289
|
+
|
|
1290
|
+
FreeImage_SetThumbnail(dib, parser.GetThumbnail());
|
|
1291
|
+
|
|
1292
|
+
FreeImage_CloseMemory(handle);
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
// release thumbnail
|
|
1298
|
+
FreeImage_Unload(thumbnail);
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
// --------------------------------------------------------------------------
|
|
1302
|
+
|
|
1303
|
+
static FIBITMAP * DLL_CALLCONV
|
|
1304
|
+
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
|
|
1305
|
+
if (!handle || !data ) {
|
|
1306
|
+
return NULL;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
TIFF *tif = NULL;
|
|
1310
|
+
uint32 height = 0;
|
|
1311
|
+
uint32 width = 0;
|
|
1312
|
+
uint16 bitspersample = 1;
|
|
1313
|
+
uint16 samplesperpixel = 1;
|
|
1314
|
+
uint32 rowsperstrip = (uint32)-1;
|
|
1315
|
+
uint16 photometric = PHOTOMETRIC_MINISWHITE;
|
|
1316
|
+
uint16 compression = (uint16)-1;
|
|
1317
|
+
uint16 planar_config;
|
|
1318
|
+
|
|
1319
|
+
FIBITMAP *dib = NULL;
|
|
1320
|
+
uint32 iccSize = 0; // ICC profile length
|
|
1321
|
+
void *iccBuf = NULL; // ICC profile data
|
|
1322
|
+
|
|
1323
|
+
const BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
|
|
1324
|
+
|
|
1325
|
+
try {
|
|
1326
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)data;
|
|
1327
|
+
tif = fio->tif;
|
|
1328
|
+
|
|
1329
|
+
if (page != -1) {
|
|
1330
|
+
if (!tif || !TIFFSetDirectory(tif, (uint16)page)) {
|
|
1331
|
+
throw "Error encountered while opening TIFF file";
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
const BOOL asCMYK = (flags & TIFF_CMYK) == TIFF_CMYK;
|
|
1336
|
+
|
|
1337
|
+
// first, get the photometric, the compression and basic metadata
|
|
1338
|
+
// ---------------------------------------------------------------------------------
|
|
1339
|
+
|
|
1340
|
+
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
|
|
1341
|
+
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
|
|
1342
|
+
|
|
1343
|
+
// check for HDR formats
|
|
1344
|
+
// ---------------------------------------------------------------------------------
|
|
1345
|
+
|
|
1346
|
+
if(photometric == PHOTOMETRIC_LOGLUV) {
|
|
1347
|
+
// check the compression
|
|
1348
|
+
if(compression != COMPRESSION_SGILOG && compression != COMPRESSION_SGILOG24) {
|
|
1349
|
+
throw "Only support SGILOG compressed LogLuv data";
|
|
1350
|
+
}
|
|
1351
|
+
// set decoder to output in IEEE 32-bit float XYZ values
|
|
1352
|
+
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
// ---------------------------------------------------------------------------------
|
|
1356
|
+
|
|
1357
|
+
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
|
|
1358
|
+
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
|
|
1359
|
+
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
|
|
1360
|
+
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
|
|
1361
|
+
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
|
1362
|
+
TIFFGetField(tif, TIFFTAG_ICCPROFILE, &iccSize, &iccBuf);
|
|
1363
|
+
TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
|
|
1364
|
+
|
|
1365
|
+
// check for unsupported formats
|
|
1366
|
+
// ---------------------------------------------------------------------------------
|
|
1367
|
+
|
|
1368
|
+
if(IsValidBitsPerSample(photometric, bitspersample) == FALSE) {
|
|
1369
|
+
FreeImage_OutputMessageProc(s_format_id,
|
|
1370
|
+
"Unable to handle this format: bitspersample = %d, samplesperpixel = %d, photometric = %d",
|
|
1371
|
+
(int)bitspersample, (int)samplesperpixel, (int)photometric);
|
|
1372
|
+
throw (char*)NULL;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
// ---------------------------------------------------------------------------------
|
|
1376
|
+
|
|
1377
|
+
// get image data type
|
|
1378
|
+
|
|
1379
|
+
FREE_IMAGE_TYPE image_type = ReadImageType(tif, bitspersample, samplesperpixel);
|
|
1380
|
+
|
|
1381
|
+
// get the most appropriate loading method
|
|
1382
|
+
|
|
1383
|
+
TIFFLoadMethod loadMethod = FindLoadMethod(tif, image_type, flags);
|
|
1384
|
+
|
|
1385
|
+
// ---------------------------------------------------------------------------------
|
|
1386
|
+
|
|
1387
|
+
if(loadMethod == LoadAsRBGA) {
|
|
1388
|
+
// ---------------------------------------------------------------------------------
|
|
1389
|
+
// RGB[A] loading using the TIFFReadRGBAImage() API
|
|
1390
|
+
// ---------------------------------------------------------------------------------
|
|
1391
|
+
|
|
1392
|
+
BOOL has_alpha = FALSE;
|
|
1393
|
+
|
|
1394
|
+
// Read the whole image into one big RGBA buffer and then
|
|
1395
|
+
// convert it to a DIB. This is using the traditional
|
|
1396
|
+
// TIFFReadRGBAImage() API that we trust.
|
|
1397
|
+
|
|
1398
|
+
uint32 *raster = NULL;
|
|
1399
|
+
|
|
1400
|
+
if(!header_only) {
|
|
1401
|
+
|
|
1402
|
+
raster = (uint32*)_TIFFmalloc(width * height * sizeof(uint32));
|
|
1403
|
+
if (raster == NULL) {
|
|
1404
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
// read the image in one chunk into an RGBA array
|
|
1408
|
+
|
|
1409
|
+
if (!TIFFReadRGBAImage(tif, width, height, raster, 1)) {
|
|
1410
|
+
_TIFFfree(raster);
|
|
1411
|
+
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
// TIFFReadRGBAImage always deliveres 3 or 4 samples per pixel images
|
|
1415
|
+
// (RGB or RGBA, see below). Cut-off possibly present channels (additional
|
|
1416
|
+
// alpha channels) from e.g. Photoshop. Any CMYK(A..) is now treated as RGB,
|
|
1417
|
+
// any additional alpha channel on RGB(AA..) is lost on conversion to RGB(A)
|
|
1418
|
+
|
|
1419
|
+
if(samplesperpixel > 4) { // TODO Write to Extra Channels
|
|
1420
|
+
FreeImage_OutputMessageProc(s_format_id, "Warning: %d additional alpha channel(s) ignored", samplesperpixel-4);
|
|
1421
|
+
samplesperpixel = 4;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
// create a new DIB (take care of different samples-per-pixel in case
|
|
1425
|
+
// of converted CMYK image (RGB conversion is on sample per pixel less)
|
|
1426
|
+
|
|
1427
|
+
if (photometric == PHOTOMETRIC_SEPARATED && samplesperpixel == 4) {
|
|
1428
|
+
samplesperpixel = 3;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
|
|
1432
|
+
if (dib == NULL) {
|
|
1433
|
+
// free the raster pointer and output an error if allocation failed
|
|
1434
|
+
if(raster) {
|
|
1435
|
+
_TIFFfree(raster);
|
|
1436
|
+
}
|
|
1437
|
+
throw FI_MSG_ERROR_DIB_MEMORY;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
// fill in the resolution (english or universal)
|
|
1441
|
+
|
|
1442
|
+
ReadResolution(tif, dib);
|
|
1443
|
+
|
|
1444
|
+
if(!header_only) {
|
|
1445
|
+
|
|
1446
|
+
// read the raster lines and save them in the DIB
|
|
1447
|
+
// with RGB mode, we have to change the order of the 3 samples RGB
|
|
1448
|
+
// We use macros for extracting components from the packed ABGR
|
|
1449
|
+
// form returned by TIFFReadRGBAImage.
|
|
1450
|
+
|
|
1451
|
+
uint32 *row = &raster[0];
|
|
1452
|
+
|
|
1453
|
+
if (samplesperpixel == 4) {
|
|
1454
|
+
// 32-bit RGBA
|
|
1455
|
+
for (uint32 y = 0; y < height; y++) {
|
|
1456
|
+
BYTE *bits = FreeImage_GetScanLine(dib, y);
|
|
1457
|
+
for (uint32 x = 0; x < width; x++) {
|
|
1458
|
+
bits[FI_RGBA_BLUE] = (BYTE)TIFFGetB(row[x]);
|
|
1459
|
+
bits[FI_RGBA_GREEN] = (BYTE)TIFFGetG(row[x]);
|
|
1460
|
+
bits[FI_RGBA_RED] = (BYTE)TIFFGetR(row[x]);
|
|
1461
|
+
bits[FI_RGBA_ALPHA] = (BYTE)TIFFGetA(row[x]);
|
|
1462
|
+
|
|
1463
|
+
if (bits[FI_RGBA_ALPHA] != 0) {
|
|
1464
|
+
has_alpha = TRUE;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
bits += 4;
|
|
1468
|
+
}
|
|
1469
|
+
row += width;
|
|
1470
|
+
}
|
|
1471
|
+
} else {
|
|
1472
|
+
// 24-bit RGB
|
|
1473
|
+
for (uint32 y = 0; y < height; y++) {
|
|
1474
|
+
BYTE *bits = FreeImage_GetScanLine(dib, y);
|
|
1475
|
+
for (uint32 x = 0; x < width; x++) {
|
|
1476
|
+
bits[FI_RGBA_BLUE] = (BYTE)TIFFGetB(row[x]);
|
|
1477
|
+
bits[FI_RGBA_GREEN] = (BYTE)TIFFGetG(row[x]);
|
|
1478
|
+
bits[FI_RGBA_RED] = (BYTE)TIFFGetR(row[x]);
|
|
1479
|
+
|
|
1480
|
+
bits += 3;
|
|
1481
|
+
}
|
|
1482
|
+
row += width;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
_TIFFfree(raster);
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
// ### Not correct when header only
|
|
1490
|
+
FreeImage_SetTransparent(dib, has_alpha);
|
|
1491
|
+
|
|
1492
|
+
} else if(loadMethod == LoadAs8BitTrns) {
|
|
1493
|
+
// ---------------------------------------------------------------------------------
|
|
1494
|
+
// 8-bit + 8-bit alpha layer loading
|
|
1495
|
+
// ---------------------------------------------------------------------------------
|
|
1496
|
+
|
|
1497
|
+
// create a new 8-bit DIB
|
|
1498
|
+
dib = CreateImageType(header_only, image_type, width, height, bitspersample, MIN<uint16>(2, samplesperpixel));
|
|
1499
|
+
if (dib == NULL) {
|
|
1500
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
// fill in the resolution (english or universal)
|
|
1504
|
+
|
|
1505
|
+
ReadResolution(tif, dib);
|
|
1506
|
+
|
|
1507
|
+
// set up the colormap based on photometric
|
|
1508
|
+
|
|
1509
|
+
ReadPalette(tif, photometric, bitspersample, dib);
|
|
1510
|
+
|
|
1511
|
+
// calculate the line + pitch (separate for scr & dest)
|
|
1512
|
+
|
|
1513
|
+
const tmsize_t src_line = TIFFScanlineSize(tif);
|
|
1514
|
+
// here, the pitch is 2x less than the original as we only keep the first layer
|
|
1515
|
+
int dst_pitch = FreeImage_GetPitch(dib);
|
|
1516
|
+
|
|
1517
|
+
// transparency table for 8-bit + 8-bit alpha images
|
|
1518
|
+
|
|
1519
|
+
BYTE trns[256];
|
|
1520
|
+
// clear the transparency table
|
|
1521
|
+
memset(trns, 0xFF, 256 * sizeof(BYTE));
|
|
1522
|
+
|
|
1523
|
+
// In the tiff file the lines are saved from up to down
|
|
1524
|
+
// In a DIB the lines must be saved from down to up
|
|
1525
|
+
|
|
1526
|
+
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
|
|
1527
|
+
|
|
1528
|
+
// read the tiff lines and save them in the DIB
|
|
1529
|
+
|
|
1530
|
+
if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
|
|
1531
|
+
|
|
1532
|
+
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
|
|
1533
|
+
if(buf == NULL) {
|
|
1534
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
for (uint32 y = 0; y < height; y += rowsperstrip) {
|
|
1538
|
+
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
|
|
1539
|
+
|
|
1540
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
|
|
1541
|
+
free(buf);
|
|
1542
|
+
throw FI_MSG_ERROR_PARSING;
|
|
1543
|
+
}
|
|
1544
|
+
for (int l = 0; l < nrow; l++) {
|
|
1545
|
+
BYTE *p = bits;
|
|
1546
|
+
BYTE *b = buf + l * src_line;
|
|
1547
|
+
|
|
1548
|
+
for(uint32 x = 0; x < (uint32)(src_line / samplesperpixel); x++) {
|
|
1549
|
+
// copy the 8-bit layer
|
|
1550
|
+
*p = b[0];
|
|
1551
|
+
// convert the 8-bit alpha layer to a trns table
|
|
1552
|
+
trns[ b[0] ] = b[1];
|
|
1553
|
+
|
|
1554
|
+
p++;
|
|
1555
|
+
b += samplesperpixel;
|
|
1556
|
+
}
|
|
1557
|
+
bits -= dst_pitch;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
free(buf);
|
|
1562
|
+
}
|
|
1563
|
+
else if(planar_config == PLANARCONFIG_SEPARATE && !header_only) {
|
|
1564
|
+
tmsize_t stripsize = TIFFStripSize(tif) * sizeof(BYTE);
|
|
1565
|
+
BYTE *buf = (BYTE*)malloc(2 * stripsize);
|
|
1566
|
+
if(buf == NULL) {
|
|
1567
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1568
|
+
}
|
|
1569
|
+
BYTE *grey = buf;
|
|
1570
|
+
BYTE *alpha = buf + stripsize;
|
|
1571
|
+
|
|
1572
|
+
for (uint32 y = 0; y < height; y += rowsperstrip) {
|
|
1573
|
+
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
|
|
1574
|
+
|
|
1575
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), grey, nrow * src_line) == -1) {
|
|
1576
|
+
free(buf);
|
|
1577
|
+
throw FI_MSG_ERROR_PARSING;
|
|
1578
|
+
}
|
|
1579
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 1), alpha, nrow * src_line) == -1) {
|
|
1580
|
+
free(buf);
|
|
1581
|
+
throw FI_MSG_ERROR_PARSING;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
for (int l = 0; l < nrow; l++) {
|
|
1585
|
+
BYTE *p = bits;
|
|
1586
|
+
BYTE *g = grey + l * src_line;
|
|
1587
|
+
BYTE *a = alpha + l * src_line;
|
|
1588
|
+
|
|
1589
|
+
for(uint32 x = 0; x < (uint32)(src_line); x++) {
|
|
1590
|
+
// copy the 8-bit layer
|
|
1591
|
+
*p = g[0];
|
|
1592
|
+
// convert the 8-bit alpha layer to a trns table
|
|
1593
|
+
trns[ g[0] ] = a[0];
|
|
1594
|
+
|
|
1595
|
+
p++;
|
|
1596
|
+
g++;
|
|
1597
|
+
a++;
|
|
1598
|
+
}
|
|
1599
|
+
bits -= dst_pitch;
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
free(buf);
|
|
1604
|
+
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
FreeImage_SetTransparencyTable(dib, &trns[0], 256);
|
|
1608
|
+
FreeImage_SetTransparent(dib, TRUE);
|
|
1609
|
+
|
|
1610
|
+
} else if(loadMethod == LoadAsCMYK) {
|
|
1611
|
+
// ---------------------------------------------------------------------------------
|
|
1612
|
+
// CMYK loading
|
|
1613
|
+
// ---------------------------------------------------------------------------------
|
|
1614
|
+
|
|
1615
|
+
// At this place, samplesperpixel could be > 4, esp. when a CMYK(A) format
|
|
1616
|
+
// is recognized. Where all other formats are handled straight-forward, this
|
|
1617
|
+
// format has to be handled special
|
|
1618
|
+
|
|
1619
|
+
BOOL isCMYKA = (photometric == PHOTOMETRIC_SEPARATED) && (samplesperpixel > 4);
|
|
1620
|
+
|
|
1621
|
+
// We use a temp dib to store the alpha for the CMYKA to RGBA conversion
|
|
1622
|
+
// NOTE this is until we have Extra channels implementation.
|
|
1623
|
+
// Also then it will be possible to merge LoadAsCMYK with LoadAsGenericStrip
|
|
1624
|
+
|
|
1625
|
+
FIBITMAP *alpha = NULL;
|
|
1626
|
+
unsigned alpha_pitch = 0;
|
|
1627
|
+
BYTE *alpha_bits = NULL;
|
|
1628
|
+
unsigned alpha_Bpp = 0;
|
|
1629
|
+
|
|
1630
|
+
if(isCMYKA && !asCMYK && !header_only) {
|
|
1631
|
+
if(bitspersample == 16) {
|
|
1632
|
+
alpha = FreeImage_AllocateT(FIT_UINT16, width, height);
|
|
1633
|
+
} else if (bitspersample == 8) {
|
|
1634
|
+
alpha = FreeImage_Allocate(width, height, 8);
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
if(!alpha) {
|
|
1638
|
+
FreeImage_OutputMessageProc(s_format_id, "Failed to allocate temporary alpha channel");
|
|
1639
|
+
} else {
|
|
1640
|
+
alpha_bits = FreeImage_GetScanLine(alpha, height - 1);
|
|
1641
|
+
alpha_pitch = FreeImage_GetPitch(alpha);
|
|
1642
|
+
alpha_Bpp = FreeImage_GetBPP(alpha) / 8;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
// create a new DIB
|
|
1648
|
+
const uint16 chCount = MIN<uint16>(samplesperpixel, 4);
|
|
1649
|
+
dib = CreateImageType(header_only, image_type, width, height, bitspersample, chCount);
|
|
1650
|
+
if (dib == NULL) {
|
|
1651
|
+
FreeImage_Unload(alpha);
|
|
1652
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
// fill in the resolution (english or universal)
|
|
1656
|
+
|
|
1657
|
+
ReadResolution(tif, dib);
|
|
1658
|
+
|
|
1659
|
+
if(!header_only) {
|
|
1660
|
+
|
|
1661
|
+
// calculate the line + pitch (separate for scr & dest)
|
|
1662
|
+
|
|
1663
|
+
const tmsize_t src_line = TIFFScanlineSize(tif);
|
|
1664
|
+
const tmsize_t dst_line = FreeImage_GetLine(dib);
|
|
1665
|
+
const unsigned dib_pitch = FreeImage_GetPitch(dib);
|
|
1666
|
+
const unsigned dibBpp = FreeImage_GetBPP(dib) / 8;
|
|
1667
|
+
const unsigned Bpc = dibBpp / chCount;
|
|
1668
|
+
const unsigned srcBpp = bitspersample * samplesperpixel / 8;
|
|
1669
|
+
|
|
1670
|
+
assert(Bpc <= 2); //< CMYK is only BYTE or SHORT
|
|
1671
|
+
|
|
1672
|
+
// In the tiff file the lines are save from up to down
|
|
1673
|
+
// In a DIB the lines must be saved from down to up
|
|
1674
|
+
|
|
1675
|
+
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
|
|
1676
|
+
|
|
1677
|
+
// read the tiff lines and save them in the DIB
|
|
1678
|
+
|
|
1679
|
+
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
|
|
1680
|
+
if(buf == NULL) {
|
|
1681
|
+
FreeImage_Unload(alpha);
|
|
1682
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
if(planar_config == PLANARCONFIG_CONTIG) {
|
|
1686
|
+
|
|
1687
|
+
// - loop for strip blocks -
|
|
1688
|
+
|
|
1689
|
+
for (uint32 y = 0; y < height; y += rowsperstrip) {
|
|
1690
|
+
const int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
|
|
1691
|
+
|
|
1692
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, strips * src_line) == -1) {
|
|
1693
|
+
free(buf);
|
|
1694
|
+
FreeImage_Unload(alpha);
|
|
1695
|
+
throw FI_MSG_ERROR_PARSING;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
// - loop for strips -
|
|
1699
|
+
|
|
1700
|
+
if(src_line != dst_line) {
|
|
1701
|
+
// CMYKA+
|
|
1702
|
+
if(alpha) {
|
|
1703
|
+
for (int l = 0; l < strips; l++) {
|
|
1704
|
+
for(BYTE *pixel = bits, *al_pixel = alpha_bits, *src_pixel = buf + l * src_line; pixel < bits + dib_pitch; pixel += dibBpp, al_pixel += alpha_Bpp, src_pixel += srcBpp) {
|
|
1705
|
+
// copy pixel byte by byte
|
|
1706
|
+
BYTE b = 0;
|
|
1707
|
+
for( ; b < dibBpp; ++b) {
|
|
1708
|
+
pixel[b] = src_pixel[b];
|
|
1709
|
+
}
|
|
1710
|
+
// TODO write the remaining bytes to extra channel(s)
|
|
1711
|
+
|
|
1712
|
+
// HACK write the first alpha to a separate dib (assume BYTE or WORD)
|
|
1713
|
+
al_pixel[0] = src_pixel[b];
|
|
1714
|
+
if(Bpc > 1) {
|
|
1715
|
+
al_pixel[1] = src_pixel[b + 1];
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
}
|
|
1719
|
+
bits -= dib_pitch;
|
|
1720
|
+
alpha_bits -= alpha_pitch;
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
else {
|
|
1724
|
+
// alpha/extra channels alloc failed
|
|
1725
|
+
for (int l = 0; l < strips; l++) {
|
|
1726
|
+
for(BYTE* pixel = bits, * src_pixel = buf + l * src_line; pixel < bits + dst_line; pixel += dibBpp, src_pixel += srcBpp) {
|
|
1727
|
+
AssignPixel(pixel, src_pixel, dibBpp);
|
|
1728
|
+
}
|
|
1729
|
+
bits -= dib_pitch;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
else {
|
|
1734
|
+
// CMYK to CMYK
|
|
1735
|
+
for (int l = 0; l < strips; l++) {
|
|
1736
|
+
BYTE *b = buf + l * src_line;
|
|
1737
|
+
memcpy(bits, b, src_line);
|
|
1738
|
+
bits -= dib_pitch;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
} // height
|
|
1743
|
+
|
|
1744
|
+
}
|
|
1745
|
+
else if(planar_config == PLANARCONFIG_SEPARATE) {
|
|
1746
|
+
|
|
1747
|
+
BYTE *dib_strip = bits;
|
|
1748
|
+
BYTE *al_strip = alpha_bits;
|
|
1749
|
+
|
|
1750
|
+
// - loop for strip blocks -
|
|
1751
|
+
|
|
1752
|
+
for (uint32 y = 0; y < height; y += rowsperstrip) {
|
|
1753
|
+
const int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
|
|
1754
|
+
|
|
1755
|
+
// - loop for channels (planes) -
|
|
1756
|
+
|
|
1757
|
+
for(uint16 sample = 0; sample < samplesperpixel; sample++) {
|
|
1758
|
+
|
|
1759
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, sample), buf, strips * src_line) == -1) {
|
|
1760
|
+
free(buf);
|
|
1761
|
+
FreeImage_Unload(alpha);
|
|
1762
|
+
throw FI_MSG_ERROR_PARSING;
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
BYTE *dst_strip = dib_strip;
|
|
1766
|
+
unsigned dst_pitch = dib_pitch;
|
|
1767
|
+
uint16 ch = sample;
|
|
1768
|
+
unsigned Bpp = dibBpp;
|
|
1769
|
+
|
|
1770
|
+
if(sample >= chCount) {
|
|
1771
|
+
// TODO Write to Extra Channel
|
|
1772
|
+
|
|
1773
|
+
// HACK redirect write to temp alpha
|
|
1774
|
+
if(alpha && sample == chCount) {
|
|
1775
|
+
|
|
1776
|
+
dst_strip = al_strip;
|
|
1777
|
+
dst_pitch = alpha_pitch;
|
|
1778
|
+
|
|
1779
|
+
ch = 0;
|
|
1780
|
+
Bpp = alpha_Bpp;
|
|
1781
|
+
}
|
|
1782
|
+
else {
|
|
1783
|
+
break;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
const unsigned channelOffset = ch * Bpc;
|
|
1788
|
+
|
|
1789
|
+
// - loop for strips in block -
|
|
1790
|
+
|
|
1791
|
+
BYTE *src_line_begin = buf;
|
|
1792
|
+
BYTE *dst_line_begin = dst_strip;
|
|
1793
|
+
for (int l = 0; l < strips; l++, src_line_begin += src_line, dst_line_begin -= dst_pitch ) {
|
|
1794
|
+
// - loop for pixels in strip -
|
|
1795
|
+
|
|
1796
|
+
const BYTE* const src_line_end = src_line_begin + src_line;
|
|
1797
|
+
for (BYTE *src_bits = src_line_begin, * dst_bits = dst_line_begin; src_bits < src_line_end; src_bits += Bpc, dst_bits += Bpp) {
|
|
1798
|
+
AssignPixel(dst_bits + channelOffset, src_bits, Bpc);
|
|
1799
|
+
} // line
|
|
1800
|
+
|
|
1801
|
+
} // strips
|
|
1802
|
+
|
|
1803
|
+
} // channels
|
|
1804
|
+
|
|
1805
|
+
// done with a strip block, incr to the next
|
|
1806
|
+
dib_strip -= strips * dib_pitch;
|
|
1807
|
+
al_strip -= strips * alpha_pitch;
|
|
1808
|
+
|
|
1809
|
+
} //< height
|
|
1810
|
+
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
free(buf);
|
|
1814
|
+
|
|
1815
|
+
if(!asCMYK) {
|
|
1816
|
+
ConvertCMYKtoRGBA(dib);
|
|
1817
|
+
|
|
1818
|
+
// The ICC Profile is invalid, clear it
|
|
1819
|
+
iccSize = 0;
|
|
1820
|
+
iccBuf = NULL;
|
|
1821
|
+
|
|
1822
|
+
if(isCMYKA) {
|
|
1823
|
+
// HACK until we have Extra channels. (ConvertCMYKtoRGBA will then do the work)
|
|
1824
|
+
|
|
1825
|
+
FreeImage_SetChannel(dib, alpha, FICC_ALPHA);
|
|
1826
|
+
FreeImage_Unload(alpha);
|
|
1827
|
+
alpha = NULL;
|
|
1828
|
+
}
|
|
1829
|
+
else {
|
|
1830
|
+
FIBITMAP *t = RemoveAlphaChannel(dib);
|
|
1831
|
+
if(t) {
|
|
1832
|
+
FreeImage_Unload(dib);
|
|
1833
|
+
dib = t;
|
|
1834
|
+
}
|
|
1835
|
+
else {
|
|
1836
|
+
FreeImage_OutputMessageProc(s_format_id, "Cannot allocate memory for buffer. CMYK image converted to RGB + pending Alpha");
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
} // !header_only
|
|
1842
|
+
|
|
1843
|
+
} else if(loadMethod == LoadAsGenericStrip) {
|
|
1844
|
+
// ---------------------------------------------------------------------------------
|
|
1845
|
+
// Generic loading
|
|
1846
|
+
// ---------------------------------------------------------------------------------
|
|
1847
|
+
|
|
1848
|
+
// create a new DIB
|
|
1849
|
+
const uint16 chCount = MIN<uint16>(samplesperpixel, 4);
|
|
1850
|
+
dib = CreateImageType(header_only, image_type, width, height, bitspersample, chCount);
|
|
1851
|
+
if (dib == NULL) {
|
|
1852
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
// fill in the resolution (english or universal)
|
|
1856
|
+
|
|
1857
|
+
ReadResolution(tif, dib);
|
|
1858
|
+
|
|
1859
|
+
// set up the colormap based on photometric
|
|
1860
|
+
|
|
1861
|
+
ReadPalette(tif, photometric, bitspersample, dib);
|
|
1862
|
+
|
|
1863
|
+
if(!header_only) {
|
|
1864
|
+
// calculate the line + pitch (separate for scr & dest)
|
|
1865
|
+
|
|
1866
|
+
const tmsize_t src_line = TIFFScanlineSize(tif);
|
|
1867
|
+
const tmsize_t dst_line = FreeImage_GetLine(dib);
|
|
1868
|
+
const unsigned dst_pitch = FreeImage_GetPitch(dib);
|
|
1869
|
+
const unsigned Bpp = FreeImage_GetBPP(dib) / 8;
|
|
1870
|
+
const unsigned srcBpp = bitspersample * samplesperpixel / 8;
|
|
1871
|
+
|
|
1872
|
+
// In the tiff file the lines are save from up to down
|
|
1873
|
+
// In a DIB the lines must be saved from down to up
|
|
1874
|
+
|
|
1875
|
+
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
|
|
1876
|
+
|
|
1877
|
+
// read the tiff lines and save them in the DIB
|
|
1878
|
+
|
|
1879
|
+
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
|
|
1880
|
+
if(buf == NULL) {
|
|
1881
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1882
|
+
}
|
|
1883
|
+
memset(buf, 0, TIFFStripSize(tif) * sizeof(BYTE));
|
|
1884
|
+
|
|
1885
|
+
BOOL bThrowMessage = FALSE;
|
|
1886
|
+
|
|
1887
|
+
if(planar_config == PLANARCONFIG_CONTIG) {
|
|
1888
|
+
|
|
1889
|
+
for (uint32 y = 0; y < height; y += rowsperstrip) {
|
|
1890
|
+
int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
|
|
1891
|
+
|
|
1892
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, strips * src_line) == -1) {
|
|
1893
|
+
// ignore errors as they can be frequent and not really valid errors, especially with fax images
|
|
1894
|
+
bThrowMessage = TRUE;
|
|
1895
|
+
/*
|
|
1896
|
+
free(buf);
|
|
1897
|
+
throw FI_MSG_ERROR_PARSING;
|
|
1898
|
+
*/
|
|
1899
|
+
}
|
|
1900
|
+
if(src_line == dst_line) {
|
|
1901
|
+
// channel count match
|
|
1902
|
+
for (int l = 0; l < strips; l++) {
|
|
1903
|
+
memcpy(bits, buf + l * src_line, src_line);
|
|
1904
|
+
bits -= dst_pitch;
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
else {
|
|
1908
|
+
for (int l = 0; l < strips; l++) {
|
|
1909
|
+
for(BYTE *pixel = bits, *src_pixel = buf + l * src_line; pixel < bits + dst_pitch; pixel += Bpp, src_pixel += srcBpp) {
|
|
1910
|
+
AssignPixel(pixel, src_pixel, Bpp);
|
|
1911
|
+
}
|
|
1912
|
+
bits -= dst_pitch;
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
else if(planar_config == PLANARCONFIG_SEPARATE) {
|
|
1918
|
+
|
|
1919
|
+
const unsigned Bpc = bitspersample / 8;
|
|
1920
|
+
BYTE* dib_strip = bits;
|
|
1921
|
+
// - loop for strip blocks -
|
|
1922
|
+
|
|
1923
|
+
for (uint32 y = 0; y < height; y += rowsperstrip) {
|
|
1924
|
+
const int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
|
|
1925
|
+
|
|
1926
|
+
// - loop for channels (planes) -
|
|
1927
|
+
|
|
1928
|
+
for(uint16 sample = 0; sample < samplesperpixel; sample++) {
|
|
1929
|
+
|
|
1930
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, sample), buf, strips * src_line) == -1) {
|
|
1931
|
+
// ignore errors as they can be frequent and not really valid errors, especially with fax images
|
|
1932
|
+
bThrowMessage = TRUE;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
if(sample >= chCount) {
|
|
1936
|
+
// TODO Write to Extra Channel
|
|
1937
|
+
break;
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
const unsigned channelOffset = sample * Bpc;
|
|
1941
|
+
|
|
1942
|
+
// - loop for strips in block -
|
|
1943
|
+
|
|
1944
|
+
BYTE* src_line_begin = buf;
|
|
1945
|
+
BYTE* dst_line_begin = dib_strip;
|
|
1946
|
+
for (int l = 0; l < strips; l++, src_line_begin += src_line, dst_line_begin -= dst_pitch ) {
|
|
1947
|
+
|
|
1948
|
+
// - loop for pixels in strip -
|
|
1949
|
+
|
|
1950
|
+
const BYTE* const src_line_end = src_line_begin + src_line;
|
|
1951
|
+
|
|
1952
|
+
for (BYTE* src_bits = src_line_begin, * dst_bits = dst_line_begin; src_bits < src_line_end; src_bits += Bpc, dst_bits += Bpp) {
|
|
1953
|
+
// actually assigns channel
|
|
1954
|
+
AssignPixel(dst_bits + channelOffset, src_bits, Bpc);
|
|
1955
|
+
} // line
|
|
1956
|
+
|
|
1957
|
+
} // strips
|
|
1958
|
+
|
|
1959
|
+
} // channels
|
|
1960
|
+
|
|
1961
|
+
// done with a strip block, incr to the next
|
|
1962
|
+
dib_strip -= strips * dst_pitch;
|
|
1963
|
+
|
|
1964
|
+
} // height
|
|
1965
|
+
|
|
1966
|
+
}
|
|
1967
|
+
free(buf);
|
|
1968
|
+
|
|
1969
|
+
if(bThrowMessage) {
|
|
1970
|
+
FreeImage_OutputMessageProc(s_format_id, "Warning: parsing error. Image may be incomplete or contain invalid data !");
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
|
|
1974
|
+
SwapRedBlue32(dib);
|
|
1975
|
+
#endif
|
|
1976
|
+
|
|
1977
|
+
} // !header only
|
|
1978
|
+
|
|
1979
|
+
} else if(loadMethod == LoadAsTiled) {
|
|
1980
|
+
// ---------------------------------------------------------------------------------
|
|
1981
|
+
// Tiled image loading
|
|
1982
|
+
// ---------------------------------------------------------------------------------
|
|
1983
|
+
|
|
1984
|
+
uint32 tileWidth, tileHeight;
|
|
1985
|
+
uint32 src_line = 0;
|
|
1986
|
+
|
|
1987
|
+
// create a new DIB
|
|
1988
|
+
dib = CreateImageType( header_only, image_type, width, height, bitspersample, samplesperpixel);
|
|
1989
|
+
if (dib == NULL) {
|
|
1990
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
// fill in the resolution (english or universal)
|
|
1994
|
+
|
|
1995
|
+
ReadResolution(tif, dib);
|
|
1996
|
+
|
|
1997
|
+
// set up the colormap based on photometric
|
|
1998
|
+
|
|
1999
|
+
ReadPalette(tif, photometric, bitspersample, dib);
|
|
2000
|
+
|
|
2001
|
+
// get the tile geometry
|
|
2002
|
+
if(!TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth) || !TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileHeight)) {
|
|
2003
|
+
throw "Invalid tiled TIFF image";
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
// read the tiff lines and save them in the DIB
|
|
2007
|
+
|
|
2008
|
+
if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
|
|
2009
|
+
|
|
2010
|
+
// get the maximum number of bytes required to contain a tile
|
|
2011
|
+
tmsize_t tileSize = TIFFTileSize(tif);
|
|
2012
|
+
|
|
2013
|
+
// allocate tile buffer
|
|
2014
|
+
BYTE *tileBuffer = (BYTE*)malloc(tileSize * sizeof(BYTE));
|
|
2015
|
+
if(tileBuffer == NULL) {
|
|
2016
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
// calculate src line and dst pitch
|
|
2020
|
+
int dst_pitch = FreeImage_GetPitch(dib);
|
|
2021
|
+
uint32 tileRowSize = (uint32)TIFFTileRowSize(tif);
|
|
2022
|
+
uint32 imageRowSize = (uint32)TIFFScanlineSize(tif);
|
|
2023
|
+
|
|
2024
|
+
|
|
2025
|
+
// In the tiff file the lines are saved from up to down
|
|
2026
|
+
// In a DIB the lines must be saved from down to up
|
|
2027
|
+
|
|
2028
|
+
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
|
|
2029
|
+
|
|
2030
|
+
for (uint32 y = 0; y < height; y += tileHeight) {
|
|
2031
|
+
int32 nrows = (y + tileHeight > height ? height - y : tileHeight);
|
|
2032
|
+
|
|
2033
|
+
for (uint32 x = 0, rowSize = 0; x < width; x += tileWidth, rowSize += tileRowSize) {
|
|
2034
|
+
memset(tileBuffer, 0, tileSize);
|
|
2035
|
+
|
|
2036
|
+
// read one tile
|
|
2037
|
+
if (TIFFReadTile(tif, tileBuffer, x, y, 0, 0) < 0) {
|
|
2038
|
+
free(tileBuffer);
|
|
2039
|
+
throw "Corrupted tiled TIFF file";
|
|
2040
|
+
}
|
|
2041
|
+
// convert to strip
|
|
2042
|
+
if(x + tileWidth > width) {
|
|
2043
|
+
src_line = imageRowSize - rowSize;
|
|
2044
|
+
} else {
|
|
2045
|
+
src_line = tileRowSize;
|
|
2046
|
+
}
|
|
2047
|
+
BYTE *src_bits = tileBuffer;
|
|
2048
|
+
BYTE *dst_bits = bits + rowSize;
|
|
2049
|
+
for(int k = 0; k < nrows; k++) {
|
|
2050
|
+
memcpy(dst_bits, src_bits, src_line);
|
|
2051
|
+
src_bits += tileRowSize;
|
|
2052
|
+
dst_bits -= dst_pitch;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
bits -= nrows * dst_pitch;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
|
|
2060
|
+
SwapRedBlue32(dib);
|
|
2061
|
+
#endif
|
|
2062
|
+
free(tileBuffer);
|
|
2063
|
+
}
|
|
2064
|
+
else if(planar_config == PLANARCONFIG_SEPARATE) {
|
|
2065
|
+
throw "Separated tiled TIFF images are not supported";
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
} else if(loadMethod == LoadAsLogLuv) {
|
|
2070
|
+
// ---------------------------------------------------------------------------------
|
|
2071
|
+
// RGBF LogLuv compressed loading
|
|
2072
|
+
// ---------------------------------------------------------------------------------
|
|
2073
|
+
|
|
2074
|
+
double stonits; // input conversion to nits
|
|
2075
|
+
if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits)) {
|
|
2076
|
+
stonits = 1;
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
// create a new DIB
|
|
2080
|
+
dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
|
|
2081
|
+
if (dib == NULL) {
|
|
2082
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
// fill in the resolution (english or universal)
|
|
2086
|
+
|
|
2087
|
+
ReadResolution(tif, dib);
|
|
2088
|
+
|
|
2089
|
+
if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
|
|
2090
|
+
// calculate the line + pitch (separate for scr & dest)
|
|
2091
|
+
|
|
2092
|
+
tmsize_t src_line = TIFFScanlineSize(tif);
|
|
2093
|
+
int dst_pitch = FreeImage_GetPitch(dib);
|
|
2094
|
+
|
|
2095
|
+
// In the tiff file the lines are save from up to down
|
|
2096
|
+
// In a DIB the lines must be saved from down to up
|
|
2097
|
+
|
|
2098
|
+
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
|
|
2099
|
+
|
|
2100
|
+
// read the tiff lines and save them in the DIB
|
|
2101
|
+
|
|
2102
|
+
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
|
|
2103
|
+
if(buf == NULL) {
|
|
2104
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
for (uint32 y = 0; y < height; y += rowsperstrip) {
|
|
2108
|
+
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
|
|
2109
|
+
|
|
2110
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
|
|
2111
|
+
free(buf);
|
|
2112
|
+
throw FI_MSG_ERROR_PARSING;
|
|
2113
|
+
}
|
|
2114
|
+
// convert from XYZ to RGB
|
|
2115
|
+
for (int l = 0; l < nrow; l++) {
|
|
2116
|
+
tiff_ConvertLineXYZToRGB(bits, buf + l * src_line, stonits, width);
|
|
2117
|
+
bits -= dst_pitch;
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
free(buf);
|
|
2122
|
+
}
|
|
2123
|
+
else if(planar_config == PLANARCONFIG_SEPARATE) {
|
|
2124
|
+
// this cannot happen according to the LogLuv specification
|
|
2125
|
+
throw "Unable to handle PLANARCONFIG_SEPARATE LogLuv images";
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2128
|
+
} else if(loadMethod == LoadAsHalfFloat) {
|
|
2129
|
+
// ---------------------------------------------------------------------------------
|
|
2130
|
+
// RGBF loading from a half format
|
|
2131
|
+
// ---------------------------------------------------------------------------------
|
|
2132
|
+
|
|
2133
|
+
// create a new DIB
|
|
2134
|
+
dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
|
|
2135
|
+
if (dib == NULL) {
|
|
2136
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
// fill in the resolution (english or universal)
|
|
2140
|
+
|
|
2141
|
+
ReadResolution(tif, dib);
|
|
2142
|
+
|
|
2143
|
+
if(!header_only) {
|
|
2144
|
+
|
|
2145
|
+
// calculate the line + pitch (separate for scr & dest)
|
|
2146
|
+
|
|
2147
|
+
tmsize_t src_line = TIFFScanlineSize(tif);
|
|
2148
|
+
unsigned dst_pitch = FreeImage_GetPitch(dib);
|
|
2149
|
+
|
|
2150
|
+
// In the tiff file the lines are save from up to down
|
|
2151
|
+
// In a DIB the lines must be saved from down to up
|
|
2152
|
+
|
|
2153
|
+
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
|
|
2154
|
+
|
|
2155
|
+
// read the tiff lines and save them in the DIB
|
|
2156
|
+
|
|
2157
|
+
if(planar_config == PLANARCONFIG_CONTIG) {
|
|
2158
|
+
|
|
2159
|
+
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
|
|
2160
|
+
if(buf == NULL) {
|
|
2161
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
for (uint32 y = 0; y < height; y += rowsperstrip) {
|
|
2165
|
+
uint32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
|
|
2166
|
+
|
|
2167
|
+
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
|
|
2168
|
+
free(buf);
|
|
2169
|
+
throw FI_MSG_ERROR_PARSING;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
// convert from half (16-bit) to float (32-bit)
|
|
2173
|
+
// !!! use OpenEXR half helper class
|
|
2174
|
+
|
|
2175
|
+
half half_value;
|
|
2176
|
+
|
|
2177
|
+
for (uint32 l = 0; l < nrow; l++) {
|
|
2178
|
+
WORD *src_pixel = (WORD*)(buf + l * src_line);
|
|
2179
|
+
float *dst_pixel = (float*)bits;
|
|
2180
|
+
|
|
2181
|
+
for(tmsize_t x = 0; x < (tmsize_t)(src_line / sizeof(WORD)); x++) {
|
|
2182
|
+
half_value.setBits(src_pixel[x]);
|
|
2183
|
+
dst_pixel[x] = half_value;
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
bits -= dst_pitch;
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
free(buf);
|
|
2191
|
+
}
|
|
2192
|
+
else if(planar_config == PLANARCONFIG_SEPARATE) {
|
|
2193
|
+
// this use case was never encountered yet
|
|
2194
|
+
throw "Unable to handle PLANARCONFIG_SEPARATE RGB half float images";
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2197
|
+
} // !header only
|
|
2198
|
+
|
|
2199
|
+
} else {
|
|
2200
|
+
// ---------------------------------------------------------------------------------
|
|
2201
|
+
// Unknown or unsupported format
|
|
2202
|
+
// ---------------------------------------------------------------------------------
|
|
2203
|
+
|
|
2204
|
+
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
// copy ICC profile data (must be done after FreeImage_Allocate)
|
|
2208
|
+
|
|
2209
|
+
FreeImage_CreateICCProfile(dib, iccBuf, iccSize);
|
|
2210
|
+
if (photometric == PHOTOMETRIC_SEPARATED && asCMYK) {
|
|
2211
|
+
FreeImage_GetICCProfile(dib)->flags |= FIICC_COLOR_IS_CMYK;
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
// copy TIFF metadata (must be done after FreeImage_Allocate)
|
|
2215
|
+
|
|
2216
|
+
ReadMetadata(tif, dib);
|
|
2217
|
+
|
|
2218
|
+
// copy TIFF thumbnail (must be done after FreeImage_Allocate)
|
|
2219
|
+
|
|
2220
|
+
ReadThumbnail(io, handle, data, tif, dib);
|
|
2221
|
+
|
|
2222
|
+
return (FIBITMAP *)dib;
|
|
2223
|
+
|
|
2224
|
+
} catch (const char *message) {
|
|
2225
|
+
if(dib) {
|
|
2226
|
+
FreeImage_Unload(dib);
|
|
2227
|
+
}
|
|
2228
|
+
if(message) {
|
|
2229
|
+
FreeImage_OutputMessageProc(s_format_id, message);
|
|
2230
|
+
}
|
|
2231
|
+
return NULL;
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
// --------------------------------------------------------------------------
|
|
2237
|
+
|
|
2238
|
+
static BOOL
|
|
2239
|
+
SaveOneTIFF(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data, unsigned ifd, unsigned ifdCount) {
|
|
2240
|
+
if (!dib || !handle || !data) {
|
|
2241
|
+
return FALSE;
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
try {
|
|
2245
|
+
fi_TIFFIO *fio = (fi_TIFFIO*)data;
|
|
2246
|
+
TIFF *out = fio->tif;
|
|
2247
|
+
|
|
2248
|
+
const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
|
|
2249
|
+
|
|
2250
|
+
const uint32 width = FreeImage_GetWidth(dib);
|
|
2251
|
+
const uint32 height = FreeImage_GetHeight(dib);
|
|
2252
|
+
const uint16 bitsperpixel = (uint16)FreeImage_GetBPP(dib);
|
|
2253
|
+
|
|
2254
|
+
const FIICCPROFILE* iccProfile = FreeImage_GetICCProfile(dib);
|
|
2255
|
+
|
|
2256
|
+
// setup out-variables based on dib and flag options
|
|
2257
|
+
|
|
2258
|
+
uint16 bitspersample;
|
|
2259
|
+
uint16 samplesperpixel;
|
|
2260
|
+
uint16 photometric;
|
|
2261
|
+
|
|
2262
|
+
if(image_type == FIT_BITMAP) {
|
|
2263
|
+
// standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
|
|
2264
|
+
|
|
2265
|
+
samplesperpixel = ((bitsperpixel == 24) ? 3 : ((bitsperpixel == 32) ? 4 : 1));
|
|
2266
|
+
bitspersample = bitsperpixel / samplesperpixel;
|
|
2267
|
+
photometric = GetPhotometric(dib);
|
|
2268
|
+
|
|
2269
|
+
if((bitsperpixel == 8) && FreeImage_IsTransparent(dib)) {
|
|
2270
|
+
// 8-bit transparent picture : convert later to 8-bit + 8-bit alpha
|
|
2271
|
+
samplesperpixel = 2;
|
|
2272
|
+
bitspersample = 8;
|
|
2273
|
+
}
|
|
2274
|
+
else if(bitsperpixel == 32) {
|
|
2275
|
+
// 32-bit images : check for CMYK or alpha transparency
|
|
2276
|
+
|
|
2277
|
+
if((((iccProfile->flags & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) || ((flags & TIFF_CMYK) == TIFF_CMYK))) {
|
|
2278
|
+
// CMYK support
|
|
2279
|
+
photometric = PHOTOMETRIC_SEPARATED;
|
|
2280
|
+
TIFFSetField(out, TIFFTAG_INKSET, INKSET_CMYK);
|
|
2281
|
+
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, 4);
|
|
2282
|
+
}
|
|
2283
|
+
else if(photometric == PHOTOMETRIC_RGB) {
|
|
2284
|
+
// transparency mask support
|
|
2285
|
+
uint16 sampleinfo[1];
|
|
2286
|
+
// unassociated alpha data is transparency information
|
|
2287
|
+
sampleinfo[0] = EXTRASAMPLE_UNASSALPHA;
|
|
2288
|
+
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, sampleinfo);
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
} else if(image_type == FIT_RGB16) {
|
|
2292
|
+
// 48-bit RGB
|
|
2293
|
+
|
|
2294
|
+
samplesperpixel = 3;
|
|
2295
|
+
bitspersample = bitsperpixel / samplesperpixel;
|
|
2296
|
+
photometric = PHOTOMETRIC_RGB;
|
|
2297
|
+
} else if(image_type == FIT_RGBA16) {
|
|
2298
|
+
// 64-bit RGBA
|
|
2299
|
+
|
|
2300
|
+
samplesperpixel = 4;
|
|
2301
|
+
bitspersample = bitsperpixel / samplesperpixel;
|
|
2302
|
+
if((((iccProfile->flags & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) || ((flags & TIFF_CMYK) == TIFF_CMYK))) {
|
|
2303
|
+
// CMYK support
|
|
2304
|
+
photometric = PHOTOMETRIC_SEPARATED;
|
|
2305
|
+
TIFFSetField(out, TIFFTAG_INKSET, INKSET_CMYK);
|
|
2306
|
+
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, 4);
|
|
2307
|
+
}
|
|
2308
|
+
else {
|
|
2309
|
+
photometric = PHOTOMETRIC_RGB;
|
|
2310
|
+
// transparency mask support
|
|
2311
|
+
uint16 sampleinfo[1];
|
|
2312
|
+
// unassociated alpha data is transparency information
|
|
2313
|
+
sampleinfo[0] = EXTRASAMPLE_UNASSALPHA;
|
|
2314
|
+
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, sampleinfo);
|
|
2315
|
+
}
|
|
2316
|
+
} else if(image_type == FIT_RGBF) {
|
|
2317
|
+
// 96-bit RGBF => store with a LogLuv encoding ?
|
|
2318
|
+
|
|
2319
|
+
samplesperpixel = 3;
|
|
2320
|
+
bitspersample = bitsperpixel / samplesperpixel;
|
|
2321
|
+
// the library converts to and from floating-point XYZ CIE values
|
|
2322
|
+
if((flags & TIFF_LOGLUV) == TIFF_LOGLUV) {
|
|
2323
|
+
photometric = PHOTOMETRIC_LOGLUV;
|
|
2324
|
+
TIFFSetField(out, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
|
|
2325
|
+
// TIFFSetField(out, TIFFTAG_STONITS, 1.0); // assume unknown
|
|
2326
|
+
}
|
|
2327
|
+
else {
|
|
2328
|
+
// store with default compression (LZW) or with input compression flag
|
|
2329
|
+
photometric = PHOTOMETRIC_RGB;
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
} else if (image_type == FIT_RGBAF) {
|
|
2333
|
+
// 128-bit RGBAF => store with default compression (LZW) or with input compression flag
|
|
2334
|
+
|
|
2335
|
+
samplesperpixel = 4;
|
|
2336
|
+
bitspersample = bitsperpixel / samplesperpixel;
|
|
2337
|
+
photometric = PHOTOMETRIC_RGB;
|
|
2338
|
+
} else {
|
|
2339
|
+
// special image type (int, long, double, ...)
|
|
2340
|
+
|
|
2341
|
+
samplesperpixel = 1;
|
|
2342
|
+
bitspersample = bitsperpixel;
|
|
2343
|
+
photometric = PHOTOMETRIC_MINISBLACK;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
// set image data type
|
|
2347
|
+
|
|
2348
|
+
WriteImageType(out, image_type);
|
|
2349
|
+
|
|
2350
|
+
// write possible ICC profile
|
|
2351
|
+
|
|
2352
|
+
if (iccProfile->size && iccProfile->data) {
|
|
2353
|
+
TIFFSetField(out, TIFFTAG_ICCPROFILE, iccProfile->size, iccProfile->data);
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
// handle standard width/height/bpp stuff
|
|
2357
|
+
|
|
2358
|
+
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
|
|
2359
|
+
TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
|
|
2360
|
+
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
|
|
2361
|
+
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bitspersample);
|
|
2362
|
+
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
|
|
2363
|
+
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); // single image plane
|
|
2364
|
+
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
|
2365
|
+
TIFFSetField(out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
|
|
2366
|
+
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, (uint32) -1));
|
|
2367
|
+
|
|
2368
|
+
// handle metrics
|
|
2369
|
+
|
|
2370
|
+
WriteResolution(out, dib);
|
|
2371
|
+
|
|
2372
|
+
// multi-paging
|
|
2373
|
+
|
|
2374
|
+
if (page >= 0) {
|
|
2375
|
+
char page_number[20];
|
|
2376
|
+
sprintf(page_number, "Page %d", page);
|
|
2377
|
+
|
|
2378
|
+
TIFFSetField(out, TIFFTAG_SUBFILETYPE, (uint32)FILETYPE_PAGE);
|
|
2379
|
+
TIFFSetField(out, TIFFTAG_PAGENUMBER, (uint16)page, (uint16)0);
|
|
2380
|
+
TIFFSetField(out, TIFFTAG_PAGENAME, page_number);
|
|
2381
|
+
|
|
2382
|
+
} else {
|
|
2383
|
+
// is it a thumbnail ?
|
|
2384
|
+
TIFFSetField(out, TIFFTAG_SUBFILETYPE, (ifd == 0) ? (uint32)0 : (uint32)FILETYPE_REDUCEDIMAGE);
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
// palettes (image colormaps are automatically scaled to 16-bits)
|
|
2388
|
+
|
|
2389
|
+
if (photometric == PHOTOMETRIC_PALETTE) {
|
|
2390
|
+
uint16 *r, *g, *b;
|
|
2391
|
+
uint16 nColors = (uint16)FreeImage_GetColorsUsed(dib);
|
|
2392
|
+
RGBQUAD *pal = FreeImage_GetPalette(dib);
|
|
2393
|
+
|
|
2394
|
+
r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * nColors);
|
|
2395
|
+
if(r == NULL) {
|
|
2396
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2397
|
+
}
|
|
2398
|
+
g = r + nColors;
|
|
2399
|
+
b = g + nColors;
|
|
2400
|
+
|
|
2401
|
+
for (int i = nColors - 1; i >= 0; i--) {
|
|
2402
|
+
r[i] = SCALE((uint16)pal[i].rgbRed);
|
|
2403
|
+
g[i] = SCALE((uint16)pal[i].rgbGreen);
|
|
2404
|
+
b[i] = SCALE((uint16)pal[i].rgbBlue);
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
TIFFSetField(out, TIFFTAG_COLORMAP, r, g, b);
|
|
2408
|
+
|
|
2409
|
+
_TIFFfree(r);
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
// compression tag
|
|
2413
|
+
|
|
2414
|
+
WriteCompression(out, bitspersample, samplesperpixel, photometric, flags);
|
|
2415
|
+
|
|
2416
|
+
// metadata
|
|
2417
|
+
|
|
2418
|
+
WriteMetadata(out, dib);
|
|
2419
|
+
|
|
2420
|
+
// thumbnail tag
|
|
2421
|
+
|
|
2422
|
+
if((ifd == 0) && (ifdCount > 1)) {
|
|
2423
|
+
uint16 nsubifd = 1;
|
|
2424
|
+
uint64 subifd[1];
|
|
2425
|
+
subifd[0] = 0;
|
|
2426
|
+
TIFFSetField(out, TIFFTAG_SUBIFD, nsubifd, subifd);
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
// read the DIB lines from bottom to top
|
|
2430
|
+
// and save them in the TIF
|
|
2431
|
+
// -------------------------------------
|
|
2432
|
+
|
|
2433
|
+
const uint32 pitch = FreeImage_GetPitch(dib);
|
|
2434
|
+
|
|
2435
|
+
if(image_type == FIT_BITMAP) {
|
|
2436
|
+
// standard bitmap type
|
|
2437
|
+
|
|
2438
|
+
switch(bitsperpixel) {
|
|
2439
|
+
case 1 :
|
|
2440
|
+
case 4 :
|
|
2441
|
+
case 8 :
|
|
2442
|
+
{
|
|
2443
|
+
if((bitsperpixel == 8) && FreeImage_IsTransparent(dib)) {
|
|
2444
|
+
// 8-bit transparent picture : convert to 8-bit + 8-bit alpha
|
|
2445
|
+
|
|
2446
|
+
// get the transparency table
|
|
2447
|
+
BYTE *trns = FreeImage_GetTransparencyTable(dib);
|
|
2448
|
+
|
|
2449
|
+
BYTE *buffer = (BYTE *)malloc(2 * width * sizeof(BYTE));
|
|
2450
|
+
if(buffer == NULL) {
|
|
2451
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
for (int y = height - 1; y >= 0; y--) {
|
|
2455
|
+
BYTE *bits = FreeImage_GetScanLine(dib, y);
|
|
2456
|
+
|
|
2457
|
+
BYTE *p = bits, *b = buffer;
|
|
2458
|
+
|
|
2459
|
+
for(uint32 x = 0; x < width; x++) {
|
|
2460
|
+
// copy the 8-bit layer
|
|
2461
|
+
b[0] = *p;
|
|
2462
|
+
// convert the trns table to a 8-bit alpha layer
|
|
2463
|
+
b[1] = trns[ b[0] ];
|
|
2464
|
+
|
|
2465
|
+
p++;
|
|
2466
|
+
b += samplesperpixel;
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
// write the scanline to disc
|
|
2470
|
+
|
|
2471
|
+
TIFFWriteScanline(out, buffer, height - y - 1, 0);
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
free(buffer);
|
|
2475
|
+
}
|
|
2476
|
+
else {
|
|
2477
|
+
// other cases
|
|
2478
|
+
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
|
|
2479
|
+
if(buffer == NULL) {
|
|
2480
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
for (uint32 y = 0; y < height; y++) {
|
|
2484
|
+
// get a copy of the scanline
|
|
2485
|
+
memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
|
|
2486
|
+
// write the scanline to disc
|
|
2487
|
+
TIFFWriteScanline(out, buffer, y, 0);
|
|
2488
|
+
}
|
|
2489
|
+
free(buffer);
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
break;
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2495
|
+
case 24:
|
|
2496
|
+
case 32:
|
|
2497
|
+
{
|
|
2498
|
+
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
|
|
2499
|
+
if(buffer == NULL) {
|
|
2500
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
for (uint32 y = 0; y < height; y++) {
|
|
2504
|
+
// get a copy of the scanline
|
|
2505
|
+
|
|
2506
|
+
memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
|
|
2507
|
+
|
|
2508
|
+
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
|
|
2509
|
+
if (photometric != PHOTOMETRIC_SEPARATED) {
|
|
2510
|
+
// TIFFs store color data RGB(A) instead of BGR(A)
|
|
2511
|
+
|
|
2512
|
+
BYTE *pBuf = buffer;
|
|
2513
|
+
|
|
2514
|
+
for (uint32 x = 0; x < width; x++) {
|
|
2515
|
+
INPLACESWAP(pBuf[0], pBuf[2]);
|
|
2516
|
+
pBuf += samplesperpixel;
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
#endif
|
|
2520
|
+
// write the scanline to disc
|
|
2521
|
+
|
|
2522
|
+
TIFFWriteScanline(out, buffer, y, 0);
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
free(buffer);
|
|
2526
|
+
|
|
2527
|
+
break;
|
|
2528
|
+
}
|
|
2529
|
+
}//< switch (bitsperpixel)
|
|
2530
|
+
|
|
2531
|
+
} else if(image_type == FIT_RGBF && (flags & TIFF_LOGLUV) == TIFF_LOGLUV) {
|
|
2532
|
+
// RGBF image => store as XYZ using a LogLuv encoding
|
|
2533
|
+
|
|
2534
|
+
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
|
|
2535
|
+
if(buffer == NULL) {
|
|
2536
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
for (uint32 y = 0; y < height; y++) {
|
|
2540
|
+
// get a copy of the scanline and convert from RGB to XYZ
|
|
2541
|
+
tiff_ConvertLineRGBToXYZ(buffer, FreeImage_GetScanLine(dib, height - y - 1), width);
|
|
2542
|
+
// write the scanline to disc
|
|
2543
|
+
TIFFWriteScanline(out, buffer, y, 0);
|
|
2544
|
+
}
|
|
2545
|
+
free(buffer);
|
|
2546
|
+
} else {
|
|
2547
|
+
// just dump the dib (tiff supports all dib types)
|
|
2548
|
+
|
|
2549
|
+
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
|
|
2550
|
+
if(buffer == NULL) {
|
|
2551
|
+
throw FI_MSG_ERROR_MEMORY;
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2554
|
+
for (uint32 y = 0; y < height; y++) {
|
|
2555
|
+
// get a copy of the scanline
|
|
2556
|
+
memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
|
|
2557
|
+
// write the scanline to disc
|
|
2558
|
+
TIFFWriteScanline(out, buffer, y, 0);
|
|
2559
|
+
}
|
|
2560
|
+
free(buffer);
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2563
|
+
// write out the directory tag if we wrote a page other than -1 or if we have a thumbnail to write later
|
|
2564
|
+
|
|
2565
|
+
if( (page >= 0) || ((ifd == 0) && (ifdCount > 1)) ) {
|
|
2566
|
+
TIFFWriteDirectory(out);
|
|
2567
|
+
// else: TIFFClose will WriteDirectory
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
return TRUE;
|
|
2571
|
+
|
|
2572
|
+
} catch(const char *text) {
|
|
2573
|
+
FreeImage_OutputMessageProc(s_format_id, text);
|
|
2574
|
+
return FALSE;
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
static BOOL DLL_CALLCONV
|
|
2579
|
+
Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
|
|
2580
|
+
BOOL bResult = FALSE;
|
|
2581
|
+
|
|
2582
|
+
// handle thumbnail as SubIFD
|
|
2583
|
+
const BOOL bHasThumbnail = (FreeImage_GetThumbnail(dib) != NULL);
|
|
2584
|
+
const unsigned ifdCount = bHasThumbnail ? 2 : 1;
|
|
2585
|
+
|
|
2586
|
+
FIBITMAP *bitmap = dib;
|
|
2587
|
+
|
|
2588
|
+
for(unsigned ifd = 0; ifd < ifdCount; ifd++) {
|
|
2589
|
+
// redirect dib to thumbnail for the second pass
|
|
2590
|
+
if(ifd == 1) {
|
|
2591
|
+
bitmap = FreeImage_GetThumbnail(dib);
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
bResult = SaveOneTIFF(io, bitmap, handle, page, flags, data, ifd, ifdCount);
|
|
2595
|
+
if(!bResult) {
|
|
2596
|
+
return FALSE;
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
return bResult;
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2603
|
+
// ==========================================================
|
|
2604
|
+
// Init
|
|
2605
|
+
// ==========================================================
|
|
2606
|
+
|
|
2607
|
+
void DLL_CALLCONV
|
|
2608
|
+
InitTIFF(Plugin *plugin, int format_id) {
|
|
2609
|
+
s_format_id = format_id;
|
|
2610
|
+
|
|
2611
|
+
// Set up the callback for extended TIFF directory tag support (see XTIFF.cpp)
|
|
2612
|
+
// Must be called before using libtiff
|
|
2613
|
+
XTIFFInitialize();
|
|
2614
|
+
|
|
2615
|
+
plugin->format_proc = Format;
|
|
2616
|
+
plugin->description_proc = Description;
|
|
2617
|
+
plugin->extension_proc = Extension;
|
|
2618
|
+
plugin->regexpr_proc = RegExpr;
|
|
2619
|
+
plugin->open_proc = Open;
|
|
2620
|
+
plugin->close_proc = Close;
|
|
2621
|
+
plugin->pagecount_proc = PageCount;
|
|
2622
|
+
plugin->pagecapability_proc = NULL;
|
|
2623
|
+
plugin->load_proc = Load;
|
|
2624
|
+
plugin->save_proc = Save;
|
|
2625
|
+
plugin->validate_proc = Validate;
|
|
2626
|
+
plugin->mime_proc = MimeType;
|
|
2627
|
+
plugin->supports_export_bpp_proc = SupportsExportDepth;
|
|
2628
|
+
plugin->supports_export_type_proc = SupportsExportType;
|
|
2629
|
+
plugin->supports_icc_profiles_proc = SupportsICCProfiles;
|
|
2630
|
+
plugin->supports_no_pixels_proc = SupportsNoPixels;
|
|
2631
|
+
}
|