pdf2json 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.
- data/README.markdown +9 -0
- data/bin/.gitkeep +0 -0
- data/ext/extconf.rb +30 -0
- data/lib/pdf2json.rb +8 -0
- data/pdf2json-0.52-source/AUTHORS +24 -0
- data/pdf2json-0.52-source/CHANGES +11 -0
- data/pdf2json-0.52-source/Makefile +84 -0
- data/pdf2json-0.52-source/Makefile.in +84 -0
- data/pdf2json-0.52-source/aclocal.m4 +274 -0
- data/pdf2json-0.52-source/aconf-win32.h +86 -0
- data/pdf2json-0.52-source/aconf.h +42 -0
- data/pdf2json-0.52-source/aconf.h.in +41 -0
- data/pdf2json-0.52-source/autom4te.cache/output.0 +6908 -0
- data/pdf2json-0.52-source/autom4te.cache/requests +76 -0
- data/pdf2json-0.52-source/autom4te.cache/traces.0 +466 -0
- data/pdf2json-0.52-source/config.log +1259 -0
- data/pdf2json-0.52-source/config.status +1050 -0
- data/pdf2json-0.52-source/configure +6908 -0
- data/pdf2json-0.52-source/configure.ac +93 -0
- data/pdf2json-0.52-source/doc/pdffonts.1 +130 -0
- data/pdf2json-0.52-source/doc/pdffonts.cat +107 -0
- data/pdf2json-0.52-source/doc/pdffonts.hlp +117 -0
- data/pdf2json-0.52-source/doc/pdfimages.1 +102 -0
- data/pdf2json-0.52-source/doc/pdfimages.cat +92 -0
- data/pdf2json-0.52-source/doc/pdfimages.hlp +101 -0
- data/pdf2json-0.52-source/doc/pdfinfo.1 +158 -0
- data/pdf2json-0.52-source/doc/pdfinfo.cat +119 -0
- data/pdf2json-0.52-source/doc/pdfinfo.hlp +129 -0
- data/pdf2json-0.52-source/doc/pdftoppm.1 +115 -0
- data/pdf2json-0.52-source/doc/pdftoppm.cat +105 -0
- data/pdf2json-0.52-source/doc/pdftoppm.hlp +114 -0
- data/pdf2json-0.52-source/doc/pdftops.1 +229 -0
- data/pdf2json-0.52-source/doc/pdftops.cat +221 -0
- data/pdf2json-0.52-source/doc/pdftops.hlp +231 -0
- data/pdf2json-0.52-source/doc/pdftotext.1 +137 -0
- data/pdf2json-0.52-source/doc/pdftotext.cat +120 -0
- data/pdf2json-0.52-source/doc/pdftotext.hlp +133 -0
- data/pdf2json-0.52-source/doc/sample-xpdfrc +91 -0
- data/pdf2json-0.52-source/doc/xpdf.1 +513 -0
- data/pdf2json-0.52-source/doc/xpdf.cat +476 -0
- data/pdf2json-0.52-source/doc/xpdf.hlp +489 -0
- data/pdf2json-0.52-source/doc/xpdfrc.5 +480 -0
- data/pdf2json-0.52-source/doc/xpdfrc.cat +474 -0
- data/pdf2json-0.52-source/doc/xpdfrc.hlp +479 -0
- data/pdf2json-0.52-source/fofi/.DS_Store +0 -0
- data/pdf2json-0.52-source/fofi/FoFiBase.cc +156 -0
- data/pdf2json-0.52-source/fofi/FoFiBase.h +57 -0
- data/pdf2json-0.52-source/fofi/FoFiBase.o +0 -0
- data/pdf2json-0.52-source/fofi/FoFiEncodings.cc +994 -0
- data/pdf2json-0.52-source/fofi/FoFiEncodings.h +36 -0
- data/pdf2json-0.52-source/fofi/FoFiEncodings.o +0 -0
- data/pdf2json-0.52-source/fofi/FoFiTrueType.cc +2027 -0
- data/pdf2json-0.52-source/fofi/FoFiTrueType.h +174 -0
- data/pdf2json-0.52-source/fofi/FoFiTrueType.o +0 -0
- data/pdf2json-0.52-source/fofi/FoFiType1.cc +252 -0
- data/pdf2json-0.52-source/fofi/FoFiType1.h +59 -0
- data/pdf2json-0.52-source/fofi/FoFiType1.o +0 -0
- data/pdf2json-0.52-source/fofi/FoFiType1C.cc +2603 -0
- data/pdf2json-0.52-source/fofi/FoFiType1C.h +233 -0
- data/pdf2json-0.52-source/fofi/FoFiType1C.o +0 -0
- data/pdf2json-0.52-source/fofi/Makefile +70 -0
- data/pdf2json-0.52-source/fofi/Makefile.dep +0 -0
- data/pdf2json-0.52-source/fofi/Makefile.in +70 -0
- data/pdf2json-0.52-source/fofi/libfofi.a +0 -0
- data/pdf2json-0.52-source/fofi/vms_make.com +0 -0
- data/pdf2json-0.52-source/freetype.win32/.DS_Store +0 -0
- data/pdf2json-0.52-source/freetype.win32/include/.DS_Store +0 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftconfig.h +528 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftheader.h +780 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftmodule.h +32 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftoption.h +733 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftstdlib.h +173 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/freetype.h +3919 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftadvanc.h +179 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbbox.h +94 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbdf.h +209 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbitmap.h +227 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcache.h +1128 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftchapters.h +103 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcid.h +166 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrdef.h +244 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrors.h +206 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgasp.h +120 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftglyph.h +613 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgxval.h +358 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgzip.h +102 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftimage.h +1313 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftincrem.h +353 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlcdfil.h +213 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlist.h +277 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlzw.h +99 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmac.h +274 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmm.h +378 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmodapi.h +483 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmoderr.h +155 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftotval.h +203 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftoutln.h +537 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftpfr.h +172 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftrender.h +230 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsizes.h +159 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsnames.h +200 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftstroke.h +716 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsynth.h +80 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsystem.h +347 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/fttrigon.h +350 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/fttypes.h +588 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftwinfnt.h +274 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftxf86.h +83 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/autohint.h +231 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftcalc.h +179 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdebug.h +250 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdriver.h +422 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftgloadr.h +168 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftmemory.h +380 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftobjs.h +1428 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftpic.h +67 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftrfork.h +196 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftserv.h +620 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftstream.h +539 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/fttrace.h +139 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftvalid.h +150 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/internal.h +51 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pcftypes.h +56 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/psaux.h +873 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pshints.h +712 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svbdf.h +77 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svcid.h +83 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgldict.h +82 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgxval.h +72 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svkern.h +51 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svmm.h +104 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svotval.h +55 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpfr.h +66 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpostnm.h +79 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpscmap.h +164 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpsinfo.h +92 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svsfnt.h +102 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttcmap.h +106 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svtteng.h +53 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttglyf.h +67 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svwinfnt.h +50 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svxf86nm.h +55 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/sfnt.h +897 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/t1types.h +270 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/tttypes.h +1543 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/t1tables.h +504 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ttnameid.h +1247 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/tttables.h +759 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/tttags.h +107 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ttunpat.h +59 -0
- data/pdf2json-0.52-source/freetype.win32/include/ft2build.h +39 -0
- data/pdf2json-0.52-source/freetype.win32/lib/freetype_a.lib +0 -0
- data/pdf2json-0.52-source/goo/.DS_Store +0 -0
- data/pdf2json-0.52-source/goo/FixedPoint.cc +118 -0
- data/pdf2json-0.52-source/goo/FixedPoint.h +155 -0
- data/pdf2json-0.52-source/goo/FixedPoint.o +0 -0
- data/pdf2json-0.52-source/goo/GHash.cc +380 -0
- data/pdf2json-0.52-source/goo/GHash.h +78 -0
- data/pdf2json-0.52-source/goo/GHash.o +0 -0
- data/pdf2json-0.52-source/goo/GList.cc +97 -0
- data/pdf2json-0.52-source/goo/GList.h +96 -0
- data/pdf2json-0.52-source/goo/GList.o +0 -0
- data/pdf2json-0.52-source/goo/GMutex.h +49 -0
- data/pdf2json-0.52-source/goo/GString.cc +724 -0
- data/pdf2json-0.52-source/goo/GString.cc.fixed +718 -0
- data/pdf2json-0.52-source/goo/GString.h +136 -0
- data/pdf2json-0.52-source/goo/GString.o +0 -0
- data/pdf2json-0.52-source/goo/ImgWriter.o +0 -0
- data/pdf2json-0.52-source/goo/JpegWriter.o +0 -0
- data/pdf2json-0.52-source/goo/Makefile +72 -0
- data/pdf2json-0.52-source/goo/Makefile.dep +0 -0
- data/pdf2json-0.52-source/goo/Makefile.in +72 -0
- data/pdf2json-0.52-source/goo/PNGWriter.o +0 -0
- data/pdf2json-0.52-source/goo/gfile.cc +731 -0
- data/pdf2json-0.52-source/goo/gfile.h +138 -0
- data/pdf2json-0.52-source/goo/gfile.o +0 -0
- data/pdf2json-0.52-source/goo/gmem.cc +264 -0
- data/pdf2json-0.52-source/goo/gmem.h +79 -0
- data/pdf2json-0.52-source/goo/gmem.o +0 -0
- data/pdf2json-0.52-source/goo/gmempp.cc +32 -0
- data/pdf2json-0.52-source/goo/gmempp.o +0 -0
- data/pdf2json-0.52-source/goo/gtypes.h +29 -0
- data/pdf2json-0.52-source/goo/libGoo.a +0 -0
- data/pdf2json-0.52-source/goo/parseargs.c +190 -0
- data/pdf2json-0.52-source/goo/parseargs.h +71 -0
- data/pdf2json-0.52-source/goo/parseargs.o +0 -0
- data/pdf2json-0.52-source/goo/vms_directory.c +214 -0
- data/pdf2json-0.52-source/goo/vms_dirent.h +67 -0
- data/pdf2json-0.52-source/goo/vms_make.com +82 -0
- data/pdf2json-0.52-source/goo/vms_sys_dirent.h +54 -0
- data/pdf2json-0.52-source/goo/vms_unix_time.h +102 -0
- data/pdf2json-0.52-source/goo/vms_unix_times.c +42 -0
- data/pdf2json-0.52-source/goo/vms_unlink.c +22 -0
- data/pdf2json-0.52-source/ms_make.bat +199 -0
- data/pdf2json-0.52-source/splash/.DS_Store +0 -0
- data/pdf2json-0.52-source/splash/Makefile +103 -0
- data/pdf2json-0.52-source/splash/Makefile.dep +0 -0
- data/pdf2json-0.52-source/splash/Makefile.in +103 -0
- data/pdf2json-0.52-source/splash/Splash.cc +3310 -0
- data/pdf2json-0.52-source/splash/Splash.h +293 -0
- data/pdf2json-0.52-source/splash/Splash.o +0 -0
- data/pdf2json-0.52-source/splash/SplashBitmap.cc +188 -0
- data/pdf2json-0.52-source/splash/SplashBitmap.h +64 -0
- data/pdf2json-0.52-source/splash/SplashBitmap.o +0 -0
- data/pdf2json-0.52-source/splash/SplashClip.cc +382 -0
- data/pdf2json-0.52-source/splash/SplashClip.h +107 -0
- data/pdf2json-0.52-source/splash/SplashClip.o +0 -0
- data/pdf2json-0.52-source/splash/SplashErrorCodes.h +32 -0
- data/pdf2json-0.52-source/splash/SplashFTFont.cc +357 -0
- data/pdf2json-0.52-source/splash/SplashFTFont.h +58 -0
- data/pdf2json-0.52-source/splash/SplashFTFont.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFTFontEngine.cc +179 -0
- data/pdf2json-0.52-source/splash/SplashFTFontEngine.h +65 -0
- data/pdf2json-0.52-source/splash/SplashFTFontEngine.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFTFontFile.cc +114 -0
- data/pdf2json-0.52-source/splash/SplashFTFontFile.h +73 -0
- data/pdf2json-0.52-source/splash/SplashFTFontFile.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFont.cc +176 -0
- data/pdf2json-0.52-source/splash/SplashFont.h +104 -0
- data/pdf2json-0.52-source/splash/SplashFont.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFontEngine.cc +317 -0
- data/pdf2json-0.52-source/splash/SplashFontEngine.h +91 -0
- data/pdf2json-0.52-source/splash/SplashFontEngine.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFontFile.cc +55 -0
- data/pdf2json-0.52-source/splash/SplashFontFile.h +60 -0
- data/pdf2json-0.52-source/splash/SplashFontFile.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFontFileID.cc +23 -0
- data/pdf2json-0.52-source/splash/SplashFontFileID.h +30 -0
- data/pdf2json-0.52-source/splash/SplashFontFileID.o +0 -0
- data/pdf2json-0.52-source/splash/SplashGlyphBitmap.h +26 -0
- data/pdf2json-0.52-source/splash/SplashMath.h +89 -0
- data/pdf2json-0.52-source/splash/SplashPath.cc +184 -0
- data/pdf2json-0.52-source/splash/SplashPath.h +121 -0
- data/pdf2json-0.52-source/splash/SplashPath.o +0 -0
- data/pdf2json-0.52-source/splash/SplashPattern.cc +40 -0
- data/pdf2json-0.52-source/splash/SplashPattern.h +65 -0
- data/pdf2json-0.52-source/splash/SplashPattern.o +0 -0
- data/pdf2json-0.52-source/splash/SplashScreen.cc +383 -0
- data/pdf2json-0.52-source/splash/SplashScreen.h +56 -0
- data/pdf2json-0.52-source/splash/SplashScreen.o +0 -0
- data/pdf2json-0.52-source/splash/SplashState.cc +165 -0
- data/pdf2json-0.52-source/splash/SplashState.h +103 -0
- data/pdf2json-0.52-source/splash/SplashState.o +0 -0
- data/pdf2json-0.52-source/splash/SplashT1Font.cc +287 -0
- data/pdf2json-0.52-source/splash/SplashT1Font.h +57 -0
- data/pdf2json-0.52-source/splash/SplashT1Font.o +0 -0
- data/pdf2json-0.52-source/splash/SplashT1FontEngine.cc +124 -0
- data/pdf2json-0.52-source/splash/SplashT1FontEngine.h +53 -0
- data/pdf2json-0.52-source/splash/SplashT1FontEngine.o +0 -0
- data/pdf2json-0.52-source/splash/SplashT1FontFile.cc +97 -0
- data/pdf2json-0.52-source/splash/SplashT1FontFile.h +58 -0
- data/pdf2json-0.52-source/splash/SplashT1FontFile.o +0 -0
- data/pdf2json-0.52-source/splash/SplashTypes.h +132 -0
- data/pdf2json-0.52-source/splash/SplashXPath.cc +438 -0
- data/pdf2json-0.52-source/splash/SplashXPath.h +100 -0
- data/pdf2json-0.52-source/splash/SplashXPath.o +0 -0
- data/pdf2json-0.52-source/splash/SplashXPathScanner.cc +428 -0
- data/pdf2json-0.52-source/splash/SplashXPathScanner.h +87 -0
- data/pdf2json-0.52-source/splash/SplashXPathScanner.o +0 -0
- data/pdf2json-0.52-source/splash/libsplash.a +0 -0
- data/pdf2json-0.52-source/splash/vms_make.com +0 -0
- data/pdf2json-0.52-source/src/.DS_Store +0 -0
- data/pdf2json-0.52-source/src/GVector.h +101 -0
- data/pdf2json-0.52-source/src/ImgOutputDev.cc +1243 -0
- data/pdf2json-0.52-source/src/ImgOutputDev.h +307 -0
- data/pdf2json-0.52-source/src/ImgOutputDev.o +0 -0
- data/pdf2json-0.52-source/src/Makefile +68 -0
- data/pdf2json-0.52-source/src/Makefile.in +68 -0
- data/pdf2json-0.52-source/src/XmlFonts.cc +367 -0
- data/pdf2json-0.52-source/src/XmlFonts.h +91 -0
- data/pdf2json-0.52-source/src/XmlFonts.o +0 -0
- data/pdf2json-0.52-source/src/XmlLinks.cc +101 -0
- data/pdf2json-0.52-source/src/XmlLinks.h +54 -0
- data/pdf2json-0.52-source/src/XmlLinks.o +0 -0
- data/pdf2json-0.52-source/src/pdf2json +0 -0
- data/pdf2json-0.52-source/src/pdf2json.cc +343 -0
- data/pdf2json-0.52-source/src/pdf2json.o +0 -0
- data/pdf2json-0.52-source/src/pdf2xml.dtd +22 -0
- data/pdf2json-0.52-source/src/pdf2xmljson.dtd +9 -0
- data/pdf2json-0.52-source/xpdf/.DS_Store +0 -0
- data/pdf2json-0.52-source/xpdf/Annot.cc +1556 -0
- data/pdf2json-0.52-source/xpdf/Annot.h +142 -0
- data/pdf2json-0.52-source/xpdf/Annot.o +0 -0
- data/pdf2json-0.52-source/xpdf/Array.cc +73 -0
- data/pdf2json-0.52-source/xpdf/Array.h +58 -0
- data/pdf2json-0.52-source/xpdf/Array.o +0 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFont.cc +65 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFont.h +57 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFont.o +0 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFontTables.cc +4284 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFontTables.h +23 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFontTables.o +0 -0
- data/pdf2json-0.52-source/xpdf/CMap.cc +408 -0
- data/pdf2json-0.52-source/xpdf/CMap.h +102 -0
- data/pdf2json-0.52-source/xpdf/CMap.o +0 -0
- data/pdf2json-0.52-source/xpdf/Catalog.cc +374 -0
- data/pdf2json-0.52-source/xpdf/Catalog.h +97 -0
- data/pdf2json-0.52-source/xpdf/Catalog.o +0 -0
- data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.cc +540 -0
- data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.h +117 -0
- data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.o +0 -0
- data/pdf2json-0.52-source/xpdf/CharTypes.h +24 -0
- data/pdf2json-0.52-source/xpdf/CompactFontTables.h +464 -0
- data/pdf2json-0.52-source/xpdf/CoreOutputDev.cc +61 -0
- data/pdf2json-0.52-source/xpdf/CoreOutputDev.h +61 -0
- data/pdf2json-0.52-source/xpdf/Decrypt.cc +776 -0
- data/pdf2json-0.52-source/xpdf/Decrypt.h +95 -0
- data/pdf2json-0.52-source/xpdf/Decrypt.o +0 -0
- data/pdf2json-0.52-source/xpdf/Dict.cc +95 -0
- data/pdf2json-0.52-source/xpdf/Dict.h +77 -0
- data/pdf2json-0.52-source/xpdf/Dict.o +0 -0
- data/pdf2json-0.52-source/xpdf/Error.cc +38 -0
- data/pdf2json-0.52-source/xpdf/Error.h +23 -0
- data/pdf2json-0.52-source/xpdf/Error.o +0 -0
- data/pdf2json-0.52-source/xpdf/ErrorCodes.h +36 -0
- data/pdf2json-0.52-source/xpdf/FontEncodingTables.cc +1824 -0
- data/pdf2json-0.52-source/xpdf/FontEncodingTables.h +20 -0
- data/pdf2json-0.52-source/xpdf/FontEncodingTables.o +0 -0
- data/pdf2json-0.52-source/xpdf/Function.cc +1573 -0
- data/pdf2json-0.52-source/xpdf/Function.h +229 -0
- data/pdf2json-0.52-source/xpdf/Function.o +0 -0
- data/pdf2json-0.52-source/xpdf/Gfx.cc +4187 -0
- data/pdf2json-0.52-source/xpdf/Gfx.h +312 -0
- data/pdf2json-0.52-source/xpdf/Gfx.o +0 -0
- data/pdf2json-0.52-source/xpdf/GfxFont.cc +1568 -0
- data/pdf2json-0.52-source/xpdf/GfxFont.h +320 -0
- data/pdf2json-0.52-source/xpdf/GfxFont.o +0 -0
- data/pdf2json-0.52-source/xpdf/GfxState.cc +4137 -0
- data/pdf2json-0.52-source/xpdf/GfxState.h +1244 -0
- data/pdf2json-0.52-source/xpdf/GfxState.o +0 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.cc +2924 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.cc.old +2908 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.h +466 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.h.old +463 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.o +0 -0
- data/pdf2json-0.52-source/xpdf/ImageOutputDev.cc +195 -0
- data/pdf2json-0.52-source/xpdf/ImageOutputDev.h +76 -0
- data/pdf2json-0.52-source/xpdf/ImageOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.cc +322 -0
- data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.h +109 -0
- data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.o +0 -0
- data/pdf2json-0.52-source/xpdf/JBIG2Stream.cc +3413 -0
- data/pdf2json-0.52-source/xpdf/JBIG2Stream.h +145 -0
- data/pdf2json-0.52-source/xpdf/JBIG2Stream.o +0 -0
- data/pdf2json-0.52-source/xpdf/JPXStream.cc +3144 -0
- data/pdf2json-0.52-source/xpdf/JPXStream.h +351 -0
- data/pdf2json-0.52-source/xpdf/JPXStream.o +0 -0
- data/pdf2json-0.52-source/xpdf/Lexer.cc +485 -0
- data/pdf2json-0.52-source/xpdf/Lexer.h +80 -0
- data/pdf2json-0.52-source/xpdf/Lexer.o +0 -0
- data/pdf2json-0.52-source/xpdf/Link.cc +806 -0
- data/pdf2json-0.52-source/xpdf/Link.cc.old +784 -0
- data/pdf2json-0.52-source/xpdf/Link.h +415 -0
- data/pdf2json-0.52-source/xpdf/Link.h.old +369 -0
- data/pdf2json-0.52-source/xpdf/Link.o +0 -0
- data/pdf2json-0.52-source/xpdf/Makefile +232 -0
- data/pdf2json-0.52-source/xpdf/Makefile.dep +0 -0
- data/pdf2json-0.52-source/xpdf/Makefile.in +232 -0
- data/pdf2json-0.52-source/xpdf/NameToCharCode.cc +116 -0
- data/pdf2json-0.52-source/xpdf/NameToCharCode.h +42 -0
- data/pdf2json-0.52-source/xpdf/NameToCharCode.o +0 -0
- data/pdf2json-0.52-source/xpdf/NameToUnicodeTable.h +1097 -0
- data/pdf2json-0.52-source/xpdf/Object.cc +231 -0
- data/pdf2json-0.52-source/xpdf/Object.h +303 -0
- data/pdf2json-0.52-source/xpdf/Object.o +0 -0
- data/pdf2json-0.52-source/xpdf/Outline.cc +151 -0
- data/pdf2json-0.52-source/xpdf/Outline.h +76 -0
- data/pdf2json-0.52-source/xpdf/Outline.o +0 -0
- data/pdf2json-0.52-source/xpdf/OutputDev.cc +131 -0
- data/pdf2json-0.52-source/xpdf/OutputDev.h +253 -0
- data/pdf2json-0.52-source/xpdf/OutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/PDFCore.cc +2044 -0
- data/pdf2json-0.52-source/xpdf/PDFCore.h +321 -0
- data/pdf2json-0.52-source/xpdf/PDFDoc.cc +404 -0
- data/pdf2json-0.52-source/xpdf/PDFDoc.h +183 -0
- data/pdf2json-0.52-source/xpdf/PDFDoc.o +0 -0
- data/pdf2json-0.52-source/xpdf/PDFDocEncoding.cc +44 -0
- data/pdf2json-0.52-source/xpdf/PDFDocEncoding.h +16 -0
- data/pdf2json-0.52-source/xpdf/PDFDocEncoding.o +0 -0
- data/pdf2json-0.52-source/xpdf/PSOutputDev.cc +6224 -0
- data/pdf2json-0.52-source/xpdf/PSOutputDev.h +395 -0
- data/pdf2json-0.52-source/xpdf/PSOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/PSTokenizer.cc +135 -0
- data/pdf2json-0.52-source/xpdf/PSTokenizer.h +41 -0
- data/pdf2json-0.52-source/xpdf/PSTokenizer.o +0 -0
- data/pdf2json-0.52-source/xpdf/Page.cc +454 -0
- data/pdf2json-0.52-source/xpdf/Page.h +187 -0
- data/pdf2json-0.52-source/xpdf/Page.o +0 -0
- data/pdf2json-0.52-source/xpdf/Parser.cc +227 -0
- data/pdf2json-0.52-source/xpdf/Parser.h +59 -0
- data/pdf2json-0.52-source/xpdf/Parser.o +0 -0
- data/pdf2json-0.52-source/xpdf/PreScanOutputDev.cc +257 -0
- data/pdf2json-0.52-source/xpdf/PreScanOutputDev.h +130 -0
- data/pdf2json-0.52-source/xpdf/PreScanOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/SecurityHandler.cc +390 -0
- data/pdf2json-0.52-source/xpdf/SecurityHandler.h +160 -0
- data/pdf2json-0.52-source/xpdf/SecurityHandler.o +0 -0
- data/pdf2json-0.52-source/xpdf/SplashOutputDev.cc +2845 -0
- data/pdf2json-0.52-source/xpdf/SplashOutputDev.h +247 -0
- data/pdf2json-0.52-source/xpdf/SplashOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/Stream-CCITT.h +459 -0
- data/pdf2json-0.52-source/xpdf/Stream.cc +4627 -0
- data/pdf2json-0.52-source/xpdf/Stream.h +858 -0
- data/pdf2json-0.52-source/xpdf/Stream.o +0 -0
- data/pdf2json-0.52-source/xpdf/TextOutputDev.cc +4090 -0
- data/pdf2json-0.52-source/xpdf/TextOutputDev.h +661 -0
- data/pdf2json-0.52-source/xpdf/TextOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/UTF8.h +56 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.cc +302 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.cc.old +293 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.h +135 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.h.old +123 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.o +0 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMapTables.h +361 -0
- data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.cc +949 -0
- data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.h +20 -0
- data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.o +0 -0
- data/pdf2json-0.52-source/xpdf/XPDFApp.cc +447 -0
- data/pdf2json-0.52-source/xpdf/XPDFApp.h +114 -0
- data/pdf2json-0.52-source/xpdf/XPDFCore.cc +1655 -0
- data/pdf2json-0.52-source/xpdf/XPDFCore.h +251 -0
- data/pdf2json-0.52-source/xpdf/XPDFTree.cc +931 -0
- data/pdf2json-0.52-source/xpdf/XPDFTree.h +45 -0
- data/pdf2json-0.52-source/xpdf/XPDFTreeP.h +87 -0
- data/pdf2json-0.52-source/xpdf/XPDFViewer.cc +3488 -0
- data/pdf2json-0.52-source/xpdf/XPDFViewer.h +352 -0
- data/pdf2json-0.52-source/xpdf/XRef.cc +896 -0
- data/pdf2json-0.52-source/xpdf/XRef.h +133 -0
- data/pdf2json-0.52-source/xpdf/XRef.o +0 -0
- data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.cc +262 -0
- data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.h +341 -0
- data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.o +0 -0
- data/pdf2json-0.52-source/xpdf/about-text.h +48 -0
- data/pdf2json-0.52-source/xpdf/about.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/backArrow.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/backArrowDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/config.h +112 -0
- data/pdf2json-0.52-source/xpdf/dblLeftArrow.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/dblLeftArrowDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/dblRightArrow.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/dblRightArrowDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/find.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/findDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/forwardArrow.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/forwardArrowDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/leftArrow.xbm +5 -0
- data/pdf2json-0.52-source/xpdf/leftArrowDis.xbm +5 -0
- data/pdf2json-0.52-source/xpdf/libXpdf.a +0 -0
- data/pdf2json-0.52-source/xpdf/pdffonts +0 -0
- data/pdf2json-0.52-source/xpdf/pdffonts.cc +298 -0
- data/pdf2json-0.52-source/xpdf/pdffonts.o +0 -0
- data/pdf2json-0.52-source/xpdf/pdfimages +0 -0
- data/pdf2json-0.52-source/xpdf/pdfimages.cc +155 -0
- data/pdf2json-0.52-source/xpdf/pdfimages.o +0 -0
- data/pdf2json-0.52-source/xpdf/pdfinfo +0 -0
- data/pdf2json-0.52-source/xpdf/pdfinfo.cc +387 -0
- data/pdf2json-0.52-source/xpdf/pdfinfo.o +0 -0
- data/pdf2json-0.52-source/xpdf/pdftoppm.cc +203 -0
- data/pdf2json-0.52-source/xpdf/pdftops +0 -0
- data/pdf2json-0.52-source/xpdf/pdftops.cc +344 -0
- data/pdf2json-0.52-source/xpdf/pdftops.o +0 -0
- data/pdf2json-0.52-source/xpdf/pdftotext +0 -0
- data/pdf2json-0.52-source/xpdf/pdftotext.cc +333 -0
- data/pdf2json-0.52-source/xpdf/pdftotext.o +0 -0
- data/pdf2json-0.52-source/xpdf/print.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/printDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/rightArrow.xbm +5 -0
- data/pdf2json-0.52-source/xpdf/rightArrowDis.xbm +5 -0
- data/pdf2json-0.52-source/xpdf/vms_make.com +129 -0
- data/pdf2json-0.52-source/xpdf/xpdf.cc +344 -0
- data/pdf2json-0.52-source/xpdf/xpdfIcon.xpm +62 -0
- data/pdf2json.gemspec +29 -0
- metadata +518 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
//========================================================================
|
2
|
+
//
|
3
|
+
// JArithmeticDecoder.h
|
4
|
+
//
|
5
|
+
// Arithmetic decoder used by the JBIG2 and JPEG2000 decoders.
|
6
|
+
//
|
7
|
+
// Copyright 2002-2004 Glyph & Cog, LLC
|
8
|
+
//
|
9
|
+
//========================================================================
|
10
|
+
|
11
|
+
#ifndef JARITHMETICDECODER_H
|
12
|
+
#define JARITHMETICDECODER_H
|
13
|
+
|
14
|
+
#include <aconf.h>
|
15
|
+
|
16
|
+
#ifdef USE_GCC_PRAGMAS
|
17
|
+
#pragma interface
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#include "gtypes.h"
|
21
|
+
|
22
|
+
class Stream;
|
23
|
+
|
24
|
+
//------------------------------------------------------------------------
|
25
|
+
// JArithmeticDecoderStats
|
26
|
+
//------------------------------------------------------------------------
|
27
|
+
|
28
|
+
class JArithmeticDecoderStats {
|
29
|
+
public:
|
30
|
+
|
31
|
+
JArithmeticDecoderStats(int contextSizeA);
|
32
|
+
~JArithmeticDecoderStats();
|
33
|
+
JArithmeticDecoderStats *copy();
|
34
|
+
void reset();
|
35
|
+
int getContextSize() { return contextSize; }
|
36
|
+
void copyFrom(JArithmeticDecoderStats *stats);
|
37
|
+
void setEntry(Guint cx, int i, int mps);
|
38
|
+
|
39
|
+
private:
|
40
|
+
|
41
|
+
Guchar *cxTab; // cxTab[cx] = (i[cx] << 1) + mps[cx]
|
42
|
+
int contextSize;
|
43
|
+
|
44
|
+
friend class JArithmeticDecoder;
|
45
|
+
};
|
46
|
+
|
47
|
+
//------------------------------------------------------------------------
|
48
|
+
// JArithmeticDecoder
|
49
|
+
//------------------------------------------------------------------------
|
50
|
+
|
51
|
+
class JArithmeticDecoder {
|
52
|
+
public:
|
53
|
+
|
54
|
+
JArithmeticDecoder();
|
55
|
+
~JArithmeticDecoder();
|
56
|
+
|
57
|
+
void setStream(Stream *strA)
|
58
|
+
{ str = strA; dataLen = 0; limitStream = gFalse; }
|
59
|
+
void setStream(Stream *strA, int dataLenA)
|
60
|
+
{ str = strA; dataLen = dataLenA; limitStream = gTrue; }
|
61
|
+
|
62
|
+
// Start decoding on a new stream. This fills the byte buffers and
|
63
|
+
// runs INITDEC.
|
64
|
+
void start();
|
65
|
+
|
66
|
+
// Restart decoding on an interrupted stream. This refills the
|
67
|
+
// buffers if needed, but does not run INITDEC. (This is used in
|
68
|
+
// JPEG 2000 streams when codeblock data is split across multiple
|
69
|
+
// packets/layers.)
|
70
|
+
void restart(int dataLenA);
|
71
|
+
|
72
|
+
// Read any leftover data in the stream.
|
73
|
+
void cleanup();
|
74
|
+
|
75
|
+
// Decode one bit.
|
76
|
+
int decodeBit(Guint context, JArithmeticDecoderStats *stats);
|
77
|
+
|
78
|
+
// Decode eight bits.
|
79
|
+
int decodeByte(Guint context, JArithmeticDecoderStats *stats);
|
80
|
+
|
81
|
+
// Returns false for OOB, otherwise sets *<x> and returns true.
|
82
|
+
GBool decodeInt(int *x, JArithmeticDecoderStats *stats);
|
83
|
+
|
84
|
+
Guint decodeIAID(Guint codeLen,
|
85
|
+
JArithmeticDecoderStats *stats);
|
86
|
+
|
87
|
+
private:
|
88
|
+
|
89
|
+
Guint readByte();
|
90
|
+
int decodeIntBit(JArithmeticDecoderStats *stats);
|
91
|
+
void byteIn();
|
92
|
+
|
93
|
+
static Guint qeTab[47];
|
94
|
+
static int nmpsTab[47];
|
95
|
+
static int nlpsTab[47];
|
96
|
+
static int switchTab[47];
|
97
|
+
|
98
|
+
Guint buf0, buf1;
|
99
|
+
Guint c, a;
|
100
|
+
int ct;
|
101
|
+
|
102
|
+
Guint prev; // for the integer decoder
|
103
|
+
|
104
|
+
Stream *str;
|
105
|
+
int dataLen;
|
106
|
+
GBool limitStream;
|
107
|
+
};
|
108
|
+
|
109
|
+
#endif
|
Binary file
|
@@ -0,0 +1,3413 @@
|
|
1
|
+
//========================================================================
|
2
|
+
//
|
3
|
+
// JBIG2Stream.cc
|
4
|
+
//
|
5
|
+
// Copyright 2002-2003 Glyph & Cog, LLC
|
6
|
+
//
|
7
|
+
//========================================================================
|
8
|
+
|
9
|
+
#include <aconf.h>
|
10
|
+
|
11
|
+
#ifdef USE_GCC_PRAGMAS
|
12
|
+
#pragma implementation
|
13
|
+
#endif
|
14
|
+
|
15
|
+
#include <stdlib.h>
|
16
|
+
#include <limits.h>
|
17
|
+
#include "GList.h"
|
18
|
+
#include "Error.h"
|
19
|
+
#include "JArithmeticDecoder.h"
|
20
|
+
#include "JBIG2Stream.h"
|
21
|
+
|
22
|
+
//~ share these tables
|
23
|
+
#include "Stream-CCITT.h"
|
24
|
+
|
25
|
+
//------------------------------------------------------------------------
|
26
|
+
|
27
|
+
static int contextSize[4] = { 16, 13, 10, 10 };
|
28
|
+
static int refContextSize[2] = { 13, 10 };
|
29
|
+
|
30
|
+
//------------------------------------------------------------------------
|
31
|
+
// JBIG2HuffmanTable
|
32
|
+
//------------------------------------------------------------------------
|
33
|
+
|
34
|
+
#define jbig2HuffmanLOW 0xfffffffd
|
35
|
+
#define jbig2HuffmanOOB 0xfffffffe
|
36
|
+
#define jbig2HuffmanEOT 0xffffffff
|
37
|
+
|
38
|
+
struct JBIG2HuffmanTable {
|
39
|
+
int val;
|
40
|
+
Guint prefixLen;
|
41
|
+
Guint rangeLen; // can also be LOW, OOB, or EOT
|
42
|
+
Guint prefix;
|
43
|
+
};
|
44
|
+
|
45
|
+
JBIG2HuffmanTable huffTableA[] = {
|
46
|
+
{ 0, 1, 4, 0x000 },
|
47
|
+
{ 16, 2, 8, 0x002 },
|
48
|
+
{ 272, 3, 16, 0x006 },
|
49
|
+
{ 65808, 3, 32, 0x007 },
|
50
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
51
|
+
};
|
52
|
+
|
53
|
+
JBIG2HuffmanTable huffTableB[] = {
|
54
|
+
{ 0, 1, 0, 0x000 },
|
55
|
+
{ 1, 2, 0, 0x002 },
|
56
|
+
{ 2, 3, 0, 0x006 },
|
57
|
+
{ 3, 4, 3, 0x00e },
|
58
|
+
{ 11, 5, 6, 0x01e },
|
59
|
+
{ 75, 6, 32, 0x03e },
|
60
|
+
{ 0, 6, jbig2HuffmanOOB, 0x03f },
|
61
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
62
|
+
};
|
63
|
+
|
64
|
+
JBIG2HuffmanTable huffTableC[] = {
|
65
|
+
{ 0, 1, 0, 0x000 },
|
66
|
+
{ 1, 2, 0, 0x002 },
|
67
|
+
{ 2, 3, 0, 0x006 },
|
68
|
+
{ 3, 4, 3, 0x00e },
|
69
|
+
{ 11, 5, 6, 0x01e },
|
70
|
+
{ 0, 6, jbig2HuffmanOOB, 0x03e },
|
71
|
+
{ 75, 7, 32, 0x0fe },
|
72
|
+
{ -256, 8, 8, 0x0fe },
|
73
|
+
{ -257, 8, jbig2HuffmanLOW, 0x0ff },
|
74
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
75
|
+
};
|
76
|
+
|
77
|
+
JBIG2HuffmanTable huffTableD[] = {
|
78
|
+
{ 1, 1, 0, 0x000 },
|
79
|
+
{ 2, 2, 0, 0x002 },
|
80
|
+
{ 3, 3, 0, 0x006 },
|
81
|
+
{ 4, 4, 3, 0x00e },
|
82
|
+
{ 12, 5, 6, 0x01e },
|
83
|
+
{ 76, 5, 32, 0x01f },
|
84
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
85
|
+
};
|
86
|
+
|
87
|
+
JBIG2HuffmanTable huffTableE[] = {
|
88
|
+
{ 1, 1, 0, 0x000 },
|
89
|
+
{ 2, 2, 0, 0x002 },
|
90
|
+
{ 3, 3, 0, 0x006 },
|
91
|
+
{ 4, 4, 3, 0x00e },
|
92
|
+
{ 12, 5, 6, 0x01e },
|
93
|
+
{ 76, 6, 32, 0x03e },
|
94
|
+
{ -255, 7, 8, 0x07e },
|
95
|
+
{ -256, 7, jbig2HuffmanLOW, 0x07f },
|
96
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
97
|
+
};
|
98
|
+
|
99
|
+
JBIG2HuffmanTable huffTableF[] = {
|
100
|
+
{ 0, 2, 7, 0x000 },
|
101
|
+
{ 128, 3, 7, 0x002 },
|
102
|
+
{ 256, 3, 8, 0x003 },
|
103
|
+
{ -1024, 4, 9, 0x008 },
|
104
|
+
{ -512, 4, 8, 0x009 },
|
105
|
+
{ -256, 4, 7, 0x00a },
|
106
|
+
{ -32, 4, 5, 0x00b },
|
107
|
+
{ 512, 4, 9, 0x00c },
|
108
|
+
{ 1024, 4, 10, 0x00d },
|
109
|
+
{ -2048, 5, 10, 0x01c },
|
110
|
+
{ -128, 5, 6, 0x01d },
|
111
|
+
{ -64, 5, 5, 0x01e },
|
112
|
+
{ -2049, 6, jbig2HuffmanLOW, 0x03e },
|
113
|
+
{ 2048, 6, 32, 0x03f },
|
114
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
115
|
+
};
|
116
|
+
|
117
|
+
JBIG2HuffmanTable huffTableG[] = {
|
118
|
+
{ -512, 3, 8, 0x000 },
|
119
|
+
{ 256, 3, 8, 0x001 },
|
120
|
+
{ 512, 3, 9, 0x002 },
|
121
|
+
{ 1024, 3, 10, 0x003 },
|
122
|
+
{ -1024, 4, 9, 0x008 },
|
123
|
+
{ -256, 4, 7, 0x009 },
|
124
|
+
{ -32, 4, 5, 0x00a },
|
125
|
+
{ 0, 4, 5, 0x00b },
|
126
|
+
{ 128, 4, 7, 0x00c },
|
127
|
+
{ -128, 5, 6, 0x01a },
|
128
|
+
{ -64, 5, 5, 0x01b },
|
129
|
+
{ 32, 5, 5, 0x01c },
|
130
|
+
{ 64, 5, 6, 0x01d },
|
131
|
+
{ -1025, 5, jbig2HuffmanLOW, 0x01e },
|
132
|
+
{ 2048, 5, 32, 0x01f },
|
133
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
134
|
+
};
|
135
|
+
|
136
|
+
JBIG2HuffmanTable huffTableH[] = {
|
137
|
+
{ 0, 2, 1, 0x000 },
|
138
|
+
{ 0, 2, jbig2HuffmanOOB, 0x001 },
|
139
|
+
{ 4, 3, 4, 0x004 },
|
140
|
+
{ -1, 4, 0, 0x00a },
|
141
|
+
{ 22, 4, 4, 0x00b },
|
142
|
+
{ 38, 4, 5, 0x00c },
|
143
|
+
{ 2, 5, 0, 0x01a },
|
144
|
+
{ 70, 5, 6, 0x01b },
|
145
|
+
{ 134, 5, 7, 0x01c },
|
146
|
+
{ 3, 6, 0, 0x03a },
|
147
|
+
{ 20, 6, 1, 0x03b },
|
148
|
+
{ 262, 6, 7, 0x03c },
|
149
|
+
{ 646, 6, 10, 0x03d },
|
150
|
+
{ -2, 7, 0, 0x07c },
|
151
|
+
{ 390, 7, 8, 0x07d },
|
152
|
+
{ -15, 8, 3, 0x0fc },
|
153
|
+
{ -5, 8, 1, 0x0fd },
|
154
|
+
{ -7, 9, 1, 0x1fc },
|
155
|
+
{ -3, 9, 0, 0x1fd },
|
156
|
+
{ -16, 9, jbig2HuffmanLOW, 0x1fe },
|
157
|
+
{ 1670, 9, 32, 0x1ff },
|
158
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
159
|
+
};
|
160
|
+
|
161
|
+
JBIG2HuffmanTable huffTableI[] = {
|
162
|
+
{ 0, 2, jbig2HuffmanOOB, 0x000 },
|
163
|
+
{ -1, 3, 1, 0x002 },
|
164
|
+
{ 1, 3, 1, 0x003 },
|
165
|
+
{ 7, 3, 5, 0x004 },
|
166
|
+
{ -3, 4, 1, 0x00a },
|
167
|
+
{ 43, 4, 5, 0x00b },
|
168
|
+
{ 75, 4, 6, 0x00c },
|
169
|
+
{ 3, 5, 1, 0x01a },
|
170
|
+
{ 139, 5, 7, 0x01b },
|
171
|
+
{ 267, 5, 8, 0x01c },
|
172
|
+
{ 5, 6, 1, 0x03a },
|
173
|
+
{ 39, 6, 2, 0x03b },
|
174
|
+
{ 523, 6, 8, 0x03c },
|
175
|
+
{ 1291, 6, 11, 0x03d },
|
176
|
+
{ -5, 7, 1, 0x07c },
|
177
|
+
{ 779, 7, 9, 0x07d },
|
178
|
+
{ -31, 8, 4, 0x0fc },
|
179
|
+
{ -11, 8, 2, 0x0fd },
|
180
|
+
{ -15, 9, 2, 0x1fc },
|
181
|
+
{ -7, 9, 1, 0x1fd },
|
182
|
+
{ -32, 9, jbig2HuffmanLOW, 0x1fe },
|
183
|
+
{ 3339, 9, 32, 0x1ff },
|
184
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
185
|
+
};
|
186
|
+
|
187
|
+
JBIG2HuffmanTable huffTableJ[] = {
|
188
|
+
{ -2, 2, 2, 0x000 },
|
189
|
+
{ 6, 2, 6, 0x001 },
|
190
|
+
{ 0, 2, jbig2HuffmanOOB, 0x002 },
|
191
|
+
{ -3, 5, 0, 0x018 },
|
192
|
+
{ 2, 5, 0, 0x019 },
|
193
|
+
{ 70, 5, 5, 0x01a },
|
194
|
+
{ 3, 6, 0, 0x036 },
|
195
|
+
{ 102, 6, 5, 0x037 },
|
196
|
+
{ 134, 6, 6, 0x038 },
|
197
|
+
{ 198, 6, 7, 0x039 },
|
198
|
+
{ 326, 6, 8, 0x03a },
|
199
|
+
{ 582, 6, 9, 0x03b },
|
200
|
+
{ 1094, 6, 10, 0x03c },
|
201
|
+
{ -21, 7, 4, 0x07a },
|
202
|
+
{ -4, 7, 0, 0x07b },
|
203
|
+
{ 4, 7, 0, 0x07c },
|
204
|
+
{ 2118, 7, 11, 0x07d },
|
205
|
+
{ -5, 8, 0, 0x0fc },
|
206
|
+
{ 5, 8, 0, 0x0fd },
|
207
|
+
{ -22, 8, jbig2HuffmanLOW, 0x0fe },
|
208
|
+
{ 4166, 8, 32, 0x0ff },
|
209
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
210
|
+
};
|
211
|
+
|
212
|
+
JBIG2HuffmanTable huffTableK[] = {
|
213
|
+
{ 1, 1, 0, 0x000 },
|
214
|
+
{ 2, 2, 1, 0x002 },
|
215
|
+
{ 4, 4, 0, 0x00c },
|
216
|
+
{ 5, 4, 1, 0x00d },
|
217
|
+
{ 7, 5, 1, 0x01c },
|
218
|
+
{ 9, 5, 2, 0x01d },
|
219
|
+
{ 13, 6, 2, 0x03c },
|
220
|
+
{ 17, 7, 2, 0x07a },
|
221
|
+
{ 21, 7, 3, 0x07b },
|
222
|
+
{ 29, 7, 4, 0x07c },
|
223
|
+
{ 45, 7, 5, 0x07d },
|
224
|
+
{ 77, 7, 6, 0x07e },
|
225
|
+
{ 141, 7, 32, 0x07f },
|
226
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
227
|
+
};
|
228
|
+
|
229
|
+
JBIG2HuffmanTable huffTableL[] = {
|
230
|
+
{ 1, 1, 0, 0x000 },
|
231
|
+
{ 2, 2, 0, 0x002 },
|
232
|
+
{ 3, 3, 1, 0x006 },
|
233
|
+
{ 5, 5, 0, 0x01c },
|
234
|
+
{ 6, 5, 1, 0x01d },
|
235
|
+
{ 8, 6, 1, 0x03c },
|
236
|
+
{ 10, 7, 0, 0x07a },
|
237
|
+
{ 11, 7, 1, 0x07b },
|
238
|
+
{ 13, 7, 2, 0x07c },
|
239
|
+
{ 17, 7, 3, 0x07d },
|
240
|
+
{ 25, 7, 4, 0x07e },
|
241
|
+
{ 41, 8, 5, 0x0fe },
|
242
|
+
{ 73, 8, 32, 0x0ff },
|
243
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
244
|
+
};
|
245
|
+
|
246
|
+
JBIG2HuffmanTable huffTableM[] = {
|
247
|
+
{ 1, 1, 0, 0x000 },
|
248
|
+
{ 2, 3, 0, 0x004 },
|
249
|
+
{ 7, 3, 3, 0x005 },
|
250
|
+
{ 3, 4, 0, 0x00c },
|
251
|
+
{ 5, 4, 1, 0x00d },
|
252
|
+
{ 4, 5, 0, 0x01c },
|
253
|
+
{ 15, 6, 1, 0x03a },
|
254
|
+
{ 17, 6, 2, 0x03b },
|
255
|
+
{ 21, 6, 3, 0x03c },
|
256
|
+
{ 29, 6, 4, 0x03d },
|
257
|
+
{ 45, 6, 5, 0x03e },
|
258
|
+
{ 77, 7, 6, 0x07e },
|
259
|
+
{ 141, 7, 32, 0x07f },
|
260
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
261
|
+
};
|
262
|
+
|
263
|
+
JBIG2HuffmanTable huffTableN[] = {
|
264
|
+
{ 0, 1, 0, 0x000 },
|
265
|
+
{ -2, 3, 0, 0x004 },
|
266
|
+
{ -1, 3, 0, 0x005 },
|
267
|
+
{ 1, 3, 0, 0x006 },
|
268
|
+
{ 2, 3, 0, 0x007 },
|
269
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
270
|
+
};
|
271
|
+
|
272
|
+
JBIG2HuffmanTable huffTableO[] = {
|
273
|
+
{ 0, 1, 0, 0x000 },
|
274
|
+
{ -1, 3, 0, 0x004 },
|
275
|
+
{ 1, 3, 0, 0x005 },
|
276
|
+
{ -2, 4, 0, 0x00c },
|
277
|
+
{ 2, 4, 0, 0x00d },
|
278
|
+
{ -4, 5, 1, 0x01c },
|
279
|
+
{ 3, 5, 1, 0x01d },
|
280
|
+
{ -8, 6, 2, 0x03c },
|
281
|
+
{ 5, 6, 2, 0x03d },
|
282
|
+
{ -24, 7, 4, 0x07c },
|
283
|
+
{ 9, 7, 4, 0x07d },
|
284
|
+
{ -25, 7, jbig2HuffmanLOW, 0x07e },
|
285
|
+
{ 25, 7, 32, 0x07f },
|
286
|
+
{ 0, 0, jbig2HuffmanEOT, 0 }
|
287
|
+
};
|
288
|
+
|
289
|
+
//------------------------------------------------------------------------
|
290
|
+
// JBIG2HuffmanDecoder
|
291
|
+
//------------------------------------------------------------------------
|
292
|
+
|
293
|
+
class JBIG2HuffmanDecoder {
|
294
|
+
public:
|
295
|
+
|
296
|
+
JBIG2HuffmanDecoder();
|
297
|
+
~JBIG2HuffmanDecoder();
|
298
|
+
void setStream(Stream *strA) { str = strA; }
|
299
|
+
|
300
|
+
void reset();
|
301
|
+
|
302
|
+
// Returns false for OOB, otherwise sets *<x> and returns true.
|
303
|
+
GBool decodeInt(int *x, JBIG2HuffmanTable *table);
|
304
|
+
|
305
|
+
Guint readBits(Guint n);
|
306
|
+
Guint readBit();
|
307
|
+
|
308
|
+
// Sort the table by prefix length and assign prefix values.
|
309
|
+
void buildTable(JBIG2HuffmanTable *table, Guint len);
|
310
|
+
|
311
|
+
private:
|
312
|
+
|
313
|
+
Stream *str;
|
314
|
+
Guint buf;
|
315
|
+
Guint bufLen;
|
316
|
+
};
|
317
|
+
|
318
|
+
JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
|
319
|
+
str = NULL;
|
320
|
+
reset();
|
321
|
+
}
|
322
|
+
|
323
|
+
JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
|
324
|
+
}
|
325
|
+
|
326
|
+
void JBIG2HuffmanDecoder::reset() {
|
327
|
+
buf = 0;
|
328
|
+
bufLen = 0;
|
329
|
+
}
|
330
|
+
|
331
|
+
//~ optimize this
|
332
|
+
GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
|
333
|
+
Guint i, len, prefix;
|
334
|
+
|
335
|
+
i = 0;
|
336
|
+
len = 0;
|
337
|
+
prefix = 0;
|
338
|
+
while (table[i].rangeLen != jbig2HuffmanEOT) {
|
339
|
+
while (len < table[i].prefixLen) {
|
340
|
+
prefix = (prefix << 1) | readBit();
|
341
|
+
++len;
|
342
|
+
}
|
343
|
+
if (prefix == table[i].prefix) {
|
344
|
+
if (table[i].rangeLen == jbig2HuffmanOOB) {
|
345
|
+
return gFalse;
|
346
|
+
}
|
347
|
+
if (table[i].rangeLen == jbig2HuffmanLOW) {
|
348
|
+
*x = table[i].val - readBits(32);
|
349
|
+
} else if (table[i].rangeLen > 0) {
|
350
|
+
*x = table[i].val + readBits(table[i].rangeLen);
|
351
|
+
} else {
|
352
|
+
*x = table[i].val;
|
353
|
+
}
|
354
|
+
return gTrue;
|
355
|
+
}
|
356
|
+
++i;
|
357
|
+
}
|
358
|
+
return gFalse;
|
359
|
+
}
|
360
|
+
|
361
|
+
Guint JBIG2HuffmanDecoder::readBits(Guint n) {
|
362
|
+
Guint x, mask, nLeft;
|
363
|
+
|
364
|
+
mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
|
365
|
+
if (bufLen >= n) {
|
366
|
+
x = (buf >> (bufLen - n)) & mask;
|
367
|
+
bufLen -= n;
|
368
|
+
} else {
|
369
|
+
x = buf & ((1 << bufLen) - 1);
|
370
|
+
nLeft = n - bufLen;
|
371
|
+
bufLen = 0;
|
372
|
+
while (nLeft >= 8) {
|
373
|
+
x = (x << 8) | (str->getChar() & 0xff);
|
374
|
+
nLeft -= 8;
|
375
|
+
}
|
376
|
+
if (nLeft > 0) {
|
377
|
+
buf = str->getChar();
|
378
|
+
bufLen = 8 - nLeft;
|
379
|
+
x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
|
380
|
+
}
|
381
|
+
}
|
382
|
+
return x;
|
383
|
+
}
|
384
|
+
|
385
|
+
Guint JBIG2HuffmanDecoder::readBit() {
|
386
|
+
if (bufLen == 0) {
|
387
|
+
buf = str->getChar();
|
388
|
+
bufLen = 8;
|
389
|
+
}
|
390
|
+
--bufLen;
|
391
|
+
return (buf >> bufLen) & 1;
|
392
|
+
}
|
393
|
+
|
394
|
+
void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
|
395
|
+
Guint i, j, k, prefix;
|
396
|
+
JBIG2HuffmanTable tab;
|
397
|
+
|
398
|
+
// stable selection sort:
|
399
|
+
// - entries with prefixLen > 0, in ascending prefixLen order
|
400
|
+
// - entry with prefixLen = 0, rangeLen = EOT
|
401
|
+
// - all other entries with prefixLen = 0
|
402
|
+
// (on entry, table[len] has prefixLen = 0, rangeLen = EOT)
|
403
|
+
for (i = 0; i < len; ++i) {
|
404
|
+
for (j = i; j < len && table[j].prefixLen == 0; ++j) ;
|
405
|
+
if (j == len) {
|
406
|
+
break;
|
407
|
+
}
|
408
|
+
for (k = j + 1; k < len; ++k) {
|
409
|
+
if (table[k].prefixLen > 0 &&
|
410
|
+
table[k].prefixLen < table[j].prefixLen) {
|
411
|
+
j = k;
|
412
|
+
}
|
413
|
+
}
|
414
|
+
if (j != i) {
|
415
|
+
tab = table[j];
|
416
|
+
for (k = j; k > i; --k) {
|
417
|
+
table[k] = table[k - 1];
|
418
|
+
}
|
419
|
+
table[i] = tab;
|
420
|
+
}
|
421
|
+
}
|
422
|
+
table[i] = table[len];
|
423
|
+
|
424
|
+
// assign prefixes
|
425
|
+
i = 0;
|
426
|
+
prefix = 0;
|
427
|
+
table[i++].prefix = prefix++;
|
428
|
+
for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
|
429
|
+
prefix <<= table[i].prefixLen - table[i-1].prefixLen;
|
430
|
+
table[i].prefix = prefix++;
|
431
|
+
}
|
432
|
+
}
|
433
|
+
|
434
|
+
//------------------------------------------------------------------------
|
435
|
+
// JBIG2MMRDecoder
|
436
|
+
//------------------------------------------------------------------------
|
437
|
+
|
438
|
+
class JBIG2MMRDecoder {
|
439
|
+
public:
|
440
|
+
|
441
|
+
JBIG2MMRDecoder();
|
442
|
+
~JBIG2MMRDecoder();
|
443
|
+
void setStream(Stream *strA) { str = strA; }
|
444
|
+
void reset();
|
445
|
+
int get2DCode();
|
446
|
+
int getBlackCode();
|
447
|
+
int getWhiteCode();
|
448
|
+
Guint get24Bits();
|
449
|
+
void skipTo(Guint length);
|
450
|
+
|
451
|
+
private:
|
452
|
+
|
453
|
+
Stream *str;
|
454
|
+
Guint buf;
|
455
|
+
Guint bufLen;
|
456
|
+
Guint nBytesRead;
|
457
|
+
};
|
458
|
+
|
459
|
+
JBIG2MMRDecoder::JBIG2MMRDecoder() {
|
460
|
+
str = NULL;
|
461
|
+
reset();
|
462
|
+
}
|
463
|
+
|
464
|
+
JBIG2MMRDecoder::~JBIG2MMRDecoder() {
|
465
|
+
}
|
466
|
+
|
467
|
+
void JBIG2MMRDecoder::reset() {
|
468
|
+
buf = 0;
|
469
|
+
bufLen = 0;
|
470
|
+
nBytesRead = 0;
|
471
|
+
}
|
472
|
+
|
473
|
+
int JBIG2MMRDecoder::get2DCode() {
|
474
|
+
CCITTCode *p;
|
475
|
+
|
476
|
+
if (bufLen == 0) {
|
477
|
+
buf = str->getChar() & 0xff;
|
478
|
+
bufLen = 8;
|
479
|
+
++nBytesRead;
|
480
|
+
p = &twoDimTab1[(buf >> 1) & 0x7f];
|
481
|
+
} else if (bufLen == 8) {
|
482
|
+
p = &twoDimTab1[(buf >> 1) & 0x7f];
|
483
|
+
} else {
|
484
|
+
p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
|
485
|
+
if (p->bits < 0 || p->bits > (int)bufLen) {
|
486
|
+
buf = (buf << 8) | (str->getChar() & 0xff);
|
487
|
+
bufLen += 8;
|
488
|
+
++nBytesRead;
|
489
|
+
p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
|
490
|
+
}
|
491
|
+
}
|
492
|
+
if (p->bits < 0) {
|
493
|
+
error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
|
494
|
+
return 0;
|
495
|
+
}
|
496
|
+
bufLen -= p->bits;
|
497
|
+
return p->n;
|
498
|
+
}
|
499
|
+
|
500
|
+
int JBIG2MMRDecoder::getWhiteCode() {
|
501
|
+
CCITTCode *p;
|
502
|
+
Guint code;
|
503
|
+
|
504
|
+
if (bufLen == 0) {
|
505
|
+
buf = str->getChar() & 0xff;
|
506
|
+
bufLen = 8;
|
507
|
+
++nBytesRead;
|
508
|
+
}
|
509
|
+
while (1) {
|
510
|
+
if (bufLen >= 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
|
511
|
+
if (bufLen <= 12) {
|
512
|
+
code = buf << (12 - bufLen);
|
513
|
+
} else {
|
514
|
+
code = buf >> (bufLen - 12);
|
515
|
+
}
|
516
|
+
p = &whiteTab1[code & 0x1f];
|
517
|
+
} else {
|
518
|
+
if (bufLen <= 9) {
|
519
|
+
code = buf << (9 - bufLen);
|
520
|
+
} else {
|
521
|
+
code = buf >> (bufLen - 9);
|
522
|
+
}
|
523
|
+
p = &whiteTab2[code & 0x1ff];
|
524
|
+
}
|
525
|
+
if (p->bits > 0 && p->bits <= (int)bufLen) {
|
526
|
+
bufLen -= p->bits;
|
527
|
+
return p->n;
|
528
|
+
}
|
529
|
+
if (bufLen >= 12) {
|
530
|
+
break;
|
531
|
+
}
|
532
|
+
buf = (buf << 8) | (str->getChar() & 0xff);
|
533
|
+
bufLen += 8;
|
534
|
+
++nBytesRead;
|
535
|
+
}
|
536
|
+
error(str->getPos(), "Bad white code in JBIG2 MMR stream");
|
537
|
+
// eat a bit and return a positive number so that the caller doesn't
|
538
|
+
// go into an infinite loop
|
539
|
+
--bufLen;
|
540
|
+
return 1;
|
541
|
+
}
|
542
|
+
|
543
|
+
int JBIG2MMRDecoder::getBlackCode() {
|
544
|
+
CCITTCode *p;
|
545
|
+
Guint code;
|
546
|
+
|
547
|
+
if (bufLen == 0) {
|
548
|
+
buf = str->getChar() & 0xff;
|
549
|
+
bufLen = 8;
|
550
|
+
++nBytesRead;
|
551
|
+
}
|
552
|
+
while (1) {
|
553
|
+
if (bufLen >= 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
|
554
|
+
if (bufLen <= 13) {
|
555
|
+
code = buf << (13 - bufLen);
|
556
|
+
} else {
|
557
|
+
code = buf >> (bufLen - 13);
|
558
|
+
}
|
559
|
+
p = &blackTab1[code & 0x7f];
|
560
|
+
} else if (bufLen >= 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {
|
561
|
+
if (bufLen <= 12) {
|
562
|
+
code = buf << (12 - bufLen);
|
563
|
+
} else {
|
564
|
+
code = buf >> (bufLen - 12);
|
565
|
+
}
|
566
|
+
p = &blackTab2[(code & 0xff) - 64];
|
567
|
+
} else {
|
568
|
+
if (bufLen <= 6) {
|
569
|
+
code = buf << (6 - bufLen);
|
570
|
+
} else {
|
571
|
+
code = buf >> (bufLen - 6);
|
572
|
+
}
|
573
|
+
p = &blackTab3[code & 0x3f];
|
574
|
+
}
|
575
|
+
if (p->bits > 0 && p->bits <= (int)bufLen) {
|
576
|
+
bufLen -= p->bits;
|
577
|
+
return p->n;
|
578
|
+
}
|
579
|
+
if (bufLen >= 13) {
|
580
|
+
break;
|
581
|
+
}
|
582
|
+
buf = (buf << 8) | (str->getChar() & 0xff);
|
583
|
+
bufLen += 8;
|
584
|
+
++nBytesRead;
|
585
|
+
}
|
586
|
+
error(str->getPos(), "Bad black code in JBIG2 MMR stream");
|
587
|
+
// eat a bit and return a positive number so that the caller doesn't
|
588
|
+
// go into an infinite loop
|
589
|
+
--bufLen;
|
590
|
+
return 1;
|
591
|
+
}
|
592
|
+
|
593
|
+
Guint JBIG2MMRDecoder::get24Bits() {
|
594
|
+
while (bufLen < 24) {
|
595
|
+
buf = (buf << 8) | (str->getChar() & 0xff);
|
596
|
+
bufLen += 8;
|
597
|
+
++nBytesRead;
|
598
|
+
}
|
599
|
+
return (buf >> (bufLen - 24)) & 0xffffff;
|
600
|
+
}
|
601
|
+
|
602
|
+
void JBIG2MMRDecoder::skipTo(Guint length) {
|
603
|
+
while (nBytesRead < length) {
|
604
|
+
str->getChar();
|
605
|
+
++nBytesRead;
|
606
|
+
}
|
607
|
+
}
|
608
|
+
|
609
|
+
//------------------------------------------------------------------------
|
610
|
+
// JBIG2Segment
|
611
|
+
//------------------------------------------------------------------------
|
612
|
+
|
613
|
+
enum JBIG2SegmentType {
|
614
|
+
jbig2SegBitmap,
|
615
|
+
jbig2SegSymbolDict,
|
616
|
+
jbig2SegPatternDict,
|
617
|
+
jbig2SegCodeTable
|
618
|
+
};
|
619
|
+
|
620
|
+
class JBIG2Segment {
|
621
|
+
public:
|
622
|
+
|
623
|
+
JBIG2Segment(Guint segNumA) { segNum = segNumA; }
|
624
|
+
virtual ~JBIG2Segment() {}
|
625
|
+
void setSegNum(Guint segNumA) { segNum = segNumA; }
|
626
|
+
Guint getSegNum() { return segNum; }
|
627
|
+
virtual JBIG2SegmentType getType() = 0;
|
628
|
+
|
629
|
+
private:
|
630
|
+
|
631
|
+
Guint segNum;
|
632
|
+
};
|
633
|
+
|
634
|
+
//------------------------------------------------------------------------
|
635
|
+
// JBIG2Bitmap
|
636
|
+
//------------------------------------------------------------------------
|
637
|
+
|
638
|
+
struct JBIG2BitmapPtr {
|
639
|
+
Guchar *p;
|
640
|
+
int shift;
|
641
|
+
int x;
|
642
|
+
};
|
643
|
+
|
644
|
+
class JBIG2Bitmap: public JBIG2Segment {
|
645
|
+
public:
|
646
|
+
|
647
|
+
JBIG2Bitmap(Guint segNumA, int wA, int hA);
|
648
|
+
virtual ~JBIG2Bitmap();
|
649
|
+
virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
|
650
|
+
JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
|
651
|
+
JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
|
652
|
+
void expand(int newH, Guint pixel);
|
653
|
+
void clearToZero();
|
654
|
+
void clearToOne();
|
655
|
+
int getWidth() { return w; }
|
656
|
+
int getHeight() { return h; }
|
657
|
+
int getPixel(int x, int y)
|
658
|
+
{ return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
|
659
|
+
(data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
|
660
|
+
void setPixel(int x, int y)
|
661
|
+
{ data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }
|
662
|
+
void clearPixel(int x, int y)
|
663
|
+
{ data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }
|
664
|
+
void getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr);
|
665
|
+
int nextPixel(JBIG2BitmapPtr *ptr);
|
666
|
+
void duplicateRow(int yDest, int ySrc);
|
667
|
+
void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
|
668
|
+
Guchar *getDataPtr() { return data; }
|
669
|
+
int getDataSize() { return h * line; }
|
670
|
+
|
671
|
+
private:
|
672
|
+
|
673
|
+
JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
|
674
|
+
|
675
|
+
int w, h, line;
|
676
|
+
Guchar *data;
|
677
|
+
};
|
678
|
+
|
679
|
+
JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
|
680
|
+
JBIG2Segment(segNumA)
|
681
|
+
{
|
682
|
+
w = wA;
|
683
|
+
h = hA;
|
684
|
+
line = (wA + 7) >> 3;
|
685
|
+
if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
|
686
|
+
data = NULL;
|
687
|
+
return;
|
688
|
+
}
|
689
|
+
// need to allocate one extra guard byte for use in combine()
|
690
|
+
data = (Guchar *)gmalloc(h * line + 1);
|
691
|
+
data[h * line] = 0;
|
692
|
+
}
|
693
|
+
|
694
|
+
JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
|
695
|
+
JBIG2Segment(segNumA)
|
696
|
+
{
|
697
|
+
w = bitmap->w;
|
698
|
+
h = bitmap->h;
|
699
|
+
line = bitmap->line;
|
700
|
+
if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
|
701
|
+
data = NULL;
|
702
|
+
return;
|
703
|
+
}
|
704
|
+
// need to allocate one extra guard byte for use in combine()
|
705
|
+
data = (Guchar *)gmalloc(h * line + 1);
|
706
|
+
memcpy(data, bitmap->data, h * line);
|
707
|
+
data[h * line] = 0;
|
708
|
+
}
|
709
|
+
|
710
|
+
JBIG2Bitmap::~JBIG2Bitmap() {
|
711
|
+
gfree(data);
|
712
|
+
}
|
713
|
+
|
714
|
+
//~ optimize this
|
715
|
+
JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
|
716
|
+
JBIG2Bitmap *slice;
|
717
|
+
Guint xx, yy;
|
718
|
+
|
719
|
+
slice = new JBIG2Bitmap(0, wA, hA);
|
720
|
+
slice->clearToZero();
|
721
|
+
for (yy = 0; yy < hA; ++yy) {
|
722
|
+
for (xx = 0; xx < wA; ++xx) {
|
723
|
+
if (getPixel(x + xx, y + yy)) {
|
724
|
+
slice->setPixel(xx, yy);
|
725
|
+
}
|
726
|
+
}
|
727
|
+
}
|
728
|
+
return slice;
|
729
|
+
}
|
730
|
+
|
731
|
+
void JBIG2Bitmap::expand(int newH, Guint pixel) {
|
732
|
+
if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
|
733
|
+
return;
|
734
|
+
}
|
735
|
+
// need to allocate one extra guard byte for use in combine()
|
736
|
+
data = (Guchar *)grealloc(data, newH * line + 1);
|
737
|
+
if (pixel) {
|
738
|
+
memset(data + h * line, 0xff, (newH - h) * line);
|
739
|
+
} else {
|
740
|
+
memset(data + h * line, 0x00, (newH - h) * line);
|
741
|
+
}
|
742
|
+
h = newH;
|
743
|
+
data[h * line] = 0;
|
744
|
+
}
|
745
|
+
|
746
|
+
void JBIG2Bitmap::clearToZero() {
|
747
|
+
memset(data, 0, h * line);
|
748
|
+
}
|
749
|
+
|
750
|
+
void JBIG2Bitmap::clearToOne() {
|
751
|
+
memset(data, 0xff, h * line);
|
752
|
+
}
|
753
|
+
|
754
|
+
inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
|
755
|
+
if (y < 0 || y >= h || x >= w) {
|
756
|
+
ptr->p = NULL;
|
757
|
+
} else if (x < 0) {
|
758
|
+
ptr->p = &data[y * line];
|
759
|
+
ptr->shift = 7;
|
760
|
+
ptr->x = x;
|
761
|
+
} else {
|
762
|
+
ptr->p = &data[y * line + (x >> 3)];
|
763
|
+
ptr->shift = 7 - (x & 7);
|
764
|
+
ptr->x = x;
|
765
|
+
}
|
766
|
+
}
|
767
|
+
|
768
|
+
inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
|
769
|
+
int pix;
|
770
|
+
|
771
|
+
if (!ptr->p) {
|
772
|
+
pix = 0;
|
773
|
+
} else if (ptr->x < 0) {
|
774
|
+
++ptr->x;
|
775
|
+
pix = 0;
|
776
|
+
} else {
|
777
|
+
pix = (*ptr->p >> ptr->shift) & 1;
|
778
|
+
if (++ptr->x == w) {
|
779
|
+
ptr->p = NULL;
|
780
|
+
} else if (ptr->shift == 0) {
|
781
|
+
++ptr->p;
|
782
|
+
ptr->shift = 7;
|
783
|
+
} else {
|
784
|
+
--ptr->shift;
|
785
|
+
}
|
786
|
+
}
|
787
|
+
return pix;
|
788
|
+
}
|
789
|
+
|
790
|
+
void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
|
791
|
+
memcpy(data + yDest * line, data + ySrc * line, line);
|
792
|
+
}
|
793
|
+
|
794
|
+
void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
|
795
|
+
Guint combOp) {
|
796
|
+
int x0, x1, y0, y1, xx, yy;
|
797
|
+
Guchar *srcPtr, *destPtr;
|
798
|
+
Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
|
799
|
+
GBool oneByte;
|
800
|
+
|
801
|
+
if (y < 0) {
|
802
|
+
y0 = -y;
|
803
|
+
} else {
|
804
|
+
y0 = 0;
|
805
|
+
}
|
806
|
+
if (y + bitmap->h > h) {
|
807
|
+
y1 = h - y;
|
808
|
+
} else {
|
809
|
+
y1 = bitmap->h;
|
810
|
+
}
|
811
|
+
if (y0 >= y1) {
|
812
|
+
return;
|
813
|
+
}
|
814
|
+
|
815
|
+
if (x >= 0) {
|
816
|
+
x0 = x & ~7;
|
817
|
+
} else {
|
818
|
+
x0 = 0;
|
819
|
+
}
|
820
|
+
x1 = x + bitmap->w;
|
821
|
+
if (x1 > w) {
|
822
|
+
x1 = w;
|
823
|
+
}
|
824
|
+
if (x0 >= x1) {
|
825
|
+
return;
|
826
|
+
}
|
827
|
+
|
828
|
+
s1 = x & 7;
|
829
|
+
s2 = 8 - s1;
|
830
|
+
m1 = 0xff >> (x1 & 7);
|
831
|
+
m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
|
832
|
+
m3 = (0xff >> s1) & m2;
|
833
|
+
|
834
|
+
oneByte = x0 == ((x1 - 1) & ~7);
|
835
|
+
|
836
|
+
for (yy = y0; yy < y1; ++yy) {
|
837
|
+
|
838
|
+
// one byte per line -- need to mask both left and right side
|
839
|
+
if (oneByte) {
|
840
|
+
if (x >= 0) {
|
841
|
+
destPtr = data + (y + yy) * line + (x >> 3);
|
842
|
+
srcPtr = bitmap->data + yy * bitmap->line;
|
843
|
+
dest = *destPtr;
|
844
|
+
src1 = *srcPtr;
|
845
|
+
switch (combOp) {
|
846
|
+
case 0: // or
|
847
|
+
dest |= (src1 >> s1) & m2;
|
848
|
+
break;
|
849
|
+
case 1: // and
|
850
|
+
dest &= ((0xff00 | src1) >> s1) | m1;
|
851
|
+
break;
|
852
|
+
case 2: // xor
|
853
|
+
dest ^= (src1 >> s1) & m2;
|
854
|
+
break;
|
855
|
+
case 3: // xnor
|
856
|
+
dest ^= ((src1 ^ 0xff) >> s1) & m2;
|
857
|
+
break;
|
858
|
+
case 4: // replace
|
859
|
+
dest = (dest & ~m3) | ((src1 >> s1) & m3);
|
860
|
+
break;
|
861
|
+
}
|
862
|
+
*destPtr = dest;
|
863
|
+
} else {
|
864
|
+
destPtr = data + (y + yy) * line;
|
865
|
+
srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
|
866
|
+
dest = *destPtr;
|
867
|
+
src1 = *srcPtr;
|
868
|
+
switch (combOp) {
|
869
|
+
case 0: // or
|
870
|
+
dest |= src1 & m2;
|
871
|
+
break;
|
872
|
+
case 1: // and
|
873
|
+
dest &= src1 | m1;
|
874
|
+
break;
|
875
|
+
case 2: // xor
|
876
|
+
dest ^= src1 & m2;
|
877
|
+
break;
|
878
|
+
case 3: // xnor
|
879
|
+
dest ^= (src1 ^ 0xff) & m2;
|
880
|
+
break;
|
881
|
+
case 4: // replace
|
882
|
+
dest = (src1 & m2) | (dest & m1);
|
883
|
+
break;
|
884
|
+
}
|
885
|
+
*destPtr = dest;
|
886
|
+
}
|
887
|
+
|
888
|
+
// multiple bytes per line -- need to mask left side of left-most
|
889
|
+
// byte and right side of right-most byte
|
890
|
+
} else {
|
891
|
+
|
892
|
+
// left-most byte
|
893
|
+
if (x >= 0) {
|
894
|
+
destPtr = data + (y + yy) * line + (x >> 3);
|
895
|
+
srcPtr = bitmap->data + yy * bitmap->line;
|
896
|
+
src1 = *srcPtr++;
|
897
|
+
dest = *destPtr;
|
898
|
+
switch (combOp) {
|
899
|
+
case 0: // or
|
900
|
+
dest |= src1 >> s1;
|
901
|
+
break;
|
902
|
+
case 1: // and
|
903
|
+
dest &= (0xff00 | src1) >> s1;
|
904
|
+
break;
|
905
|
+
case 2: // xor
|
906
|
+
dest ^= src1 >> s1;
|
907
|
+
break;
|
908
|
+
case 3: // xnor
|
909
|
+
dest ^= (src1 ^ 0xff) >> s1;
|
910
|
+
break;
|
911
|
+
case 4: // replace
|
912
|
+
dest = (dest & (0xff << s2)) | (src1 >> s1);
|
913
|
+
break;
|
914
|
+
}
|
915
|
+
*destPtr++ = dest;
|
916
|
+
xx = x0 + 8;
|
917
|
+
} else {
|
918
|
+
destPtr = data + (y + yy) * line;
|
919
|
+
srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
|
920
|
+
src1 = *srcPtr++;
|
921
|
+
xx = x0;
|
922
|
+
}
|
923
|
+
|
924
|
+
// middle bytes
|
925
|
+
for (; xx < x1 - 8; xx += 8) {
|
926
|
+
dest = *destPtr;
|
927
|
+
src0 = src1;
|
928
|
+
src1 = *srcPtr++;
|
929
|
+
src = (((src0 << 8) | src1) >> s1) & 0xff;
|
930
|
+
switch (combOp) {
|
931
|
+
case 0: // or
|
932
|
+
dest |= src;
|
933
|
+
break;
|
934
|
+
case 1: // and
|
935
|
+
dest &= src;
|
936
|
+
break;
|
937
|
+
case 2: // xor
|
938
|
+
dest ^= src;
|
939
|
+
break;
|
940
|
+
case 3: // xnor
|
941
|
+
dest ^= src ^ 0xff;
|
942
|
+
break;
|
943
|
+
case 4: // replace
|
944
|
+
dest = src;
|
945
|
+
break;
|
946
|
+
}
|
947
|
+
*destPtr++ = dest;
|
948
|
+
}
|
949
|
+
|
950
|
+
// right-most byte
|
951
|
+
// note: this last byte (src1) may not actually be used, depending
|
952
|
+
// on the values of s1, m1, and m2 - and in fact, it may be off
|
953
|
+
// the edge of the source bitmap, which means we need to allocate
|
954
|
+
// one extra guard byte at the end of each bitmap
|
955
|
+
dest = *destPtr;
|
956
|
+
src0 = src1;
|
957
|
+
src1 = *srcPtr++;
|
958
|
+
src = (((src0 << 8) | src1) >> s1) & 0xff;
|
959
|
+
switch (combOp) {
|
960
|
+
case 0: // or
|
961
|
+
dest |= src & m2;
|
962
|
+
break;
|
963
|
+
case 1: // and
|
964
|
+
dest &= src | m1;
|
965
|
+
break;
|
966
|
+
case 2: // xor
|
967
|
+
dest ^= src & m2;
|
968
|
+
break;
|
969
|
+
case 3: // xnor
|
970
|
+
dest ^= (src ^ 0xff) & m2;
|
971
|
+
break;
|
972
|
+
case 4: // replace
|
973
|
+
dest = (src & m2) | (dest & m1);
|
974
|
+
break;
|
975
|
+
}
|
976
|
+
*destPtr = dest;
|
977
|
+
}
|
978
|
+
}
|
979
|
+
}
|
980
|
+
|
981
|
+
//------------------------------------------------------------------------
|
982
|
+
// JBIG2SymbolDict
|
983
|
+
//------------------------------------------------------------------------
|
984
|
+
|
985
|
+
class JBIG2SymbolDict: public JBIG2Segment {
|
986
|
+
public:
|
987
|
+
|
988
|
+
JBIG2SymbolDict(Guint segNumA, Guint sizeA);
|
989
|
+
virtual ~JBIG2SymbolDict();
|
990
|
+
virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
|
991
|
+
Guint getSize() { return size; }
|
992
|
+
void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
|
993
|
+
JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
|
994
|
+
void setGenericRegionStats(JArithmeticDecoderStats *stats)
|
995
|
+
{ genericRegionStats = stats; }
|
996
|
+
void setRefinementRegionStats(JArithmeticDecoderStats *stats)
|
997
|
+
{ refinementRegionStats = stats; }
|
998
|
+
JArithmeticDecoderStats *getGenericRegionStats()
|
999
|
+
{ return genericRegionStats; }
|
1000
|
+
JArithmeticDecoderStats *getRefinementRegionStats()
|
1001
|
+
{ return refinementRegionStats; }
|
1002
|
+
|
1003
|
+
private:
|
1004
|
+
|
1005
|
+
Guint size;
|
1006
|
+
JBIG2Bitmap **bitmaps;
|
1007
|
+
JArithmeticDecoderStats *genericRegionStats;
|
1008
|
+
JArithmeticDecoderStats *refinementRegionStats;
|
1009
|
+
};
|
1010
|
+
|
1011
|
+
JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
|
1012
|
+
JBIG2Segment(segNumA)
|
1013
|
+
{
|
1014
|
+
size = sizeA;
|
1015
|
+
bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
|
1016
|
+
genericRegionStats = NULL;
|
1017
|
+
refinementRegionStats = NULL;
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
JBIG2SymbolDict::~JBIG2SymbolDict() {
|
1021
|
+
Guint i;
|
1022
|
+
|
1023
|
+
for (i = 0; i < size; ++i) {
|
1024
|
+
delete bitmaps[i];
|
1025
|
+
}
|
1026
|
+
gfree(bitmaps);
|
1027
|
+
if (genericRegionStats) {
|
1028
|
+
delete genericRegionStats;
|
1029
|
+
}
|
1030
|
+
if (refinementRegionStats) {
|
1031
|
+
delete refinementRegionStats;
|
1032
|
+
}
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
//------------------------------------------------------------------------
|
1036
|
+
// JBIG2PatternDict
|
1037
|
+
//------------------------------------------------------------------------
|
1038
|
+
|
1039
|
+
class JBIG2PatternDict: public JBIG2Segment {
|
1040
|
+
public:
|
1041
|
+
|
1042
|
+
JBIG2PatternDict(Guint segNumA, Guint sizeA);
|
1043
|
+
virtual ~JBIG2PatternDict();
|
1044
|
+
virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
|
1045
|
+
Guint getSize() { return size; }
|
1046
|
+
void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
|
1047
|
+
JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
|
1048
|
+
|
1049
|
+
private:
|
1050
|
+
|
1051
|
+
Guint size;
|
1052
|
+
JBIG2Bitmap **bitmaps;
|
1053
|
+
};
|
1054
|
+
|
1055
|
+
JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
|
1056
|
+
JBIG2Segment(segNumA)
|
1057
|
+
{
|
1058
|
+
size = sizeA;
|
1059
|
+
bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
JBIG2PatternDict::~JBIG2PatternDict() {
|
1063
|
+
Guint i;
|
1064
|
+
|
1065
|
+
for (i = 0; i < size; ++i) {
|
1066
|
+
delete bitmaps[i];
|
1067
|
+
}
|
1068
|
+
gfree(bitmaps);
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
//------------------------------------------------------------------------
|
1072
|
+
// JBIG2CodeTable
|
1073
|
+
//------------------------------------------------------------------------
|
1074
|
+
|
1075
|
+
class JBIG2CodeTable: public JBIG2Segment {
|
1076
|
+
public:
|
1077
|
+
|
1078
|
+
JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
|
1079
|
+
virtual ~JBIG2CodeTable();
|
1080
|
+
virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
|
1081
|
+
JBIG2HuffmanTable *getHuffTable() { return table; }
|
1082
|
+
|
1083
|
+
private:
|
1084
|
+
|
1085
|
+
JBIG2HuffmanTable *table;
|
1086
|
+
};
|
1087
|
+
|
1088
|
+
JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
|
1089
|
+
JBIG2Segment(segNumA)
|
1090
|
+
{
|
1091
|
+
table = tableA;
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
JBIG2CodeTable::~JBIG2CodeTable() {
|
1095
|
+
gfree(table);
|
1096
|
+
}
|
1097
|
+
|
1098
|
+
//------------------------------------------------------------------------
|
1099
|
+
// JBIG2Stream
|
1100
|
+
//------------------------------------------------------------------------
|
1101
|
+
|
1102
|
+
JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA):
|
1103
|
+
FilterStream(strA)
|
1104
|
+
{
|
1105
|
+
pageBitmap = NULL;
|
1106
|
+
|
1107
|
+
arithDecoder = new JArithmeticDecoder();
|
1108
|
+
genericRegionStats = new JArithmeticDecoderStats(1 << 1);
|
1109
|
+
refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
|
1110
|
+
iadhStats = new JArithmeticDecoderStats(1 << 9);
|
1111
|
+
iadwStats = new JArithmeticDecoderStats(1 << 9);
|
1112
|
+
iaexStats = new JArithmeticDecoderStats(1 << 9);
|
1113
|
+
iaaiStats = new JArithmeticDecoderStats(1 << 9);
|
1114
|
+
iadtStats = new JArithmeticDecoderStats(1 << 9);
|
1115
|
+
iaitStats = new JArithmeticDecoderStats(1 << 9);
|
1116
|
+
iafsStats = new JArithmeticDecoderStats(1 << 9);
|
1117
|
+
iadsStats = new JArithmeticDecoderStats(1 << 9);
|
1118
|
+
iardxStats = new JArithmeticDecoderStats(1 << 9);
|
1119
|
+
iardyStats = new JArithmeticDecoderStats(1 << 9);
|
1120
|
+
iardwStats = new JArithmeticDecoderStats(1 << 9);
|
1121
|
+
iardhStats = new JArithmeticDecoderStats(1 << 9);
|
1122
|
+
iariStats = new JArithmeticDecoderStats(1 << 9);
|
1123
|
+
iaidStats = new JArithmeticDecoderStats(1 << 1);
|
1124
|
+
huffDecoder = new JBIG2HuffmanDecoder();
|
1125
|
+
mmrDecoder = new JBIG2MMRDecoder();
|
1126
|
+
|
1127
|
+
globalsStreamA->copy(&globalsStream);
|
1128
|
+
segments = globalSegments = NULL;
|
1129
|
+
curStr = NULL;
|
1130
|
+
dataPtr = dataEnd = NULL;
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
JBIG2Stream::~JBIG2Stream() {
|
1134
|
+
close();
|
1135
|
+
globalsStream.free();
|
1136
|
+
delete arithDecoder;
|
1137
|
+
delete genericRegionStats;
|
1138
|
+
delete refinementRegionStats;
|
1139
|
+
delete iadhStats;
|
1140
|
+
delete iadwStats;
|
1141
|
+
delete iaexStats;
|
1142
|
+
delete iaaiStats;
|
1143
|
+
delete iadtStats;
|
1144
|
+
delete iaitStats;
|
1145
|
+
delete iafsStats;
|
1146
|
+
delete iadsStats;
|
1147
|
+
delete iardxStats;
|
1148
|
+
delete iardyStats;
|
1149
|
+
delete iardwStats;
|
1150
|
+
delete iardhStats;
|
1151
|
+
delete iariStats;
|
1152
|
+
delete iaidStats;
|
1153
|
+
delete huffDecoder;
|
1154
|
+
delete mmrDecoder;
|
1155
|
+
delete str;
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
void JBIG2Stream::reset() {
|
1159
|
+
// read the globals stream
|
1160
|
+
globalSegments = new GList();
|
1161
|
+
if (globalsStream.isStream()) {
|
1162
|
+
segments = globalSegments;
|
1163
|
+
curStr = globalsStream.getStream();
|
1164
|
+
curStr->reset();
|
1165
|
+
arithDecoder->setStream(curStr);
|
1166
|
+
huffDecoder->setStream(curStr);
|
1167
|
+
mmrDecoder->setStream(curStr);
|
1168
|
+
readSegments();
|
1169
|
+
curStr->close();
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
// read the main stream
|
1173
|
+
segments = new GList();
|
1174
|
+
curStr = str;
|
1175
|
+
curStr->reset();
|
1176
|
+
arithDecoder->setStream(curStr);
|
1177
|
+
huffDecoder->setStream(curStr);
|
1178
|
+
mmrDecoder->setStream(curStr);
|
1179
|
+
readSegments();
|
1180
|
+
|
1181
|
+
if (pageBitmap) {
|
1182
|
+
dataPtr = pageBitmap->getDataPtr();
|
1183
|
+
dataEnd = dataPtr + pageBitmap->getDataSize();
|
1184
|
+
} else {
|
1185
|
+
dataPtr = dataEnd = NULL;
|
1186
|
+
}
|
1187
|
+
}
|
1188
|
+
|
1189
|
+
void JBIG2Stream::close() {
|
1190
|
+
if (pageBitmap) {
|
1191
|
+
delete pageBitmap;
|
1192
|
+
pageBitmap = NULL;
|
1193
|
+
}
|
1194
|
+
if (segments) {
|
1195
|
+
deleteGList(segments, JBIG2Segment);
|
1196
|
+
segments = NULL;
|
1197
|
+
}
|
1198
|
+
if (globalSegments) {
|
1199
|
+
deleteGList(globalSegments, JBIG2Segment);
|
1200
|
+
globalSegments = NULL;
|
1201
|
+
}
|
1202
|
+
dataPtr = dataEnd = NULL;
|
1203
|
+
FilterStream::close();
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
int JBIG2Stream::getChar() {
|
1207
|
+
if (dataPtr && dataPtr < dataEnd) {
|
1208
|
+
return (*dataPtr++ ^ 0xff) & 0xff;
|
1209
|
+
}
|
1210
|
+
return EOF;
|
1211
|
+
}
|
1212
|
+
|
1213
|
+
int JBIG2Stream::lookChar() {
|
1214
|
+
if (dataPtr && dataPtr < dataEnd) {
|
1215
|
+
return (*dataPtr ^ 0xff) & 0xff;
|
1216
|
+
}
|
1217
|
+
return EOF;
|
1218
|
+
}
|
1219
|
+
|
1220
|
+
GString *JBIG2Stream::getPSFilter(int psLevel, char *indent) {
|
1221
|
+
return NULL;
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
GBool JBIG2Stream::isBinary(GBool last) {
|
1225
|
+
return str->isBinary(gTrue);
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
void JBIG2Stream::readSegments() {
|
1229
|
+
Guint segNum, segFlags, segType, page, segLength;
|
1230
|
+
Guint refFlags, nRefSegs;
|
1231
|
+
Guint *refSegs;
|
1232
|
+
int c1, c2, c3;
|
1233
|
+
Guint i;
|
1234
|
+
|
1235
|
+
while (readULong(&segNum)) {
|
1236
|
+
|
1237
|
+
// segment header flags
|
1238
|
+
if (!readUByte(&segFlags)) {
|
1239
|
+
goto eofError1;
|
1240
|
+
}
|
1241
|
+
segType = segFlags & 0x3f;
|
1242
|
+
|
1243
|
+
// referred-to segment count and retention flags
|
1244
|
+
if (!readUByte(&refFlags)) {
|
1245
|
+
goto eofError1;
|
1246
|
+
}
|
1247
|
+
nRefSegs = refFlags >> 5;
|
1248
|
+
if (nRefSegs == 7) {
|
1249
|
+
if ((c1 = curStr->getChar()) == EOF ||
|
1250
|
+
(c2 = curStr->getChar()) == EOF ||
|
1251
|
+
(c3 = curStr->getChar()) == EOF) {
|
1252
|
+
goto eofError1;
|
1253
|
+
}
|
1254
|
+
refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
|
1255
|
+
nRefSegs = refFlags & 0x1fffffff;
|
1256
|
+
for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
|
1257
|
+
c1 = curStr->getChar();
|
1258
|
+
}
|
1259
|
+
}
|
1260
|
+
|
1261
|
+
// referred-to segment numbers
|
1262
|
+
refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint));
|
1263
|
+
if (segNum <= 256) {
|
1264
|
+
for (i = 0; i < nRefSegs; ++i) {
|
1265
|
+
if (!readUByte(&refSegs[i])) {
|
1266
|
+
goto eofError2;
|
1267
|
+
}
|
1268
|
+
}
|
1269
|
+
} else if (segNum <= 65536) {
|
1270
|
+
for (i = 0; i < nRefSegs; ++i) {
|
1271
|
+
if (!readUWord(&refSegs[i])) {
|
1272
|
+
goto eofError2;
|
1273
|
+
}
|
1274
|
+
}
|
1275
|
+
} else {
|
1276
|
+
for (i = 0; i < nRefSegs; ++i) {
|
1277
|
+
if (!readULong(&refSegs[i])) {
|
1278
|
+
goto eofError2;
|
1279
|
+
}
|
1280
|
+
}
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
// segment page association
|
1284
|
+
if (segFlags & 0x40) {
|
1285
|
+
if (!readULong(&page)) {
|
1286
|
+
goto eofError2;
|
1287
|
+
}
|
1288
|
+
} else {
|
1289
|
+
if (!readUByte(&page)) {
|
1290
|
+
goto eofError2;
|
1291
|
+
}
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
// segment data length
|
1295
|
+
if (!readULong(&segLength)) {
|
1296
|
+
goto eofError2;
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
// read the segment data
|
1300
|
+
switch (segType) {
|
1301
|
+
case 0:
|
1302
|
+
if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
|
1303
|
+
goto syntaxError;
|
1304
|
+
}
|
1305
|
+
break;
|
1306
|
+
case 4:
|
1307
|
+
readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
|
1308
|
+
break;
|
1309
|
+
case 6:
|
1310
|
+
readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
|
1311
|
+
break;
|
1312
|
+
case 7:
|
1313
|
+
readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
|
1314
|
+
break;
|
1315
|
+
case 16:
|
1316
|
+
readPatternDictSeg(segNum, segLength);
|
1317
|
+
break;
|
1318
|
+
case 20:
|
1319
|
+
readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
|
1320
|
+
refSegs, nRefSegs);
|
1321
|
+
break;
|
1322
|
+
case 22:
|
1323
|
+
readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
|
1324
|
+
refSegs, nRefSegs);
|
1325
|
+
break;
|
1326
|
+
case 23:
|
1327
|
+
readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
|
1328
|
+
refSegs, nRefSegs);
|
1329
|
+
break;
|
1330
|
+
case 36:
|
1331
|
+
readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
|
1332
|
+
break;
|
1333
|
+
case 38:
|
1334
|
+
readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
|
1335
|
+
break;
|
1336
|
+
case 39:
|
1337
|
+
readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
|
1338
|
+
break;
|
1339
|
+
case 40:
|
1340
|
+
readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
|
1341
|
+
refSegs, nRefSegs);
|
1342
|
+
break;
|
1343
|
+
case 42:
|
1344
|
+
readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
|
1345
|
+
refSegs, nRefSegs);
|
1346
|
+
break;
|
1347
|
+
case 43:
|
1348
|
+
readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
|
1349
|
+
refSegs, nRefSegs);
|
1350
|
+
break;
|
1351
|
+
case 48:
|
1352
|
+
readPageInfoSeg(segLength);
|
1353
|
+
break;
|
1354
|
+
case 50:
|
1355
|
+
readEndOfStripeSeg(segLength);
|
1356
|
+
break;
|
1357
|
+
case 52:
|
1358
|
+
readProfilesSeg(segLength);
|
1359
|
+
break;
|
1360
|
+
case 53:
|
1361
|
+
readCodeTableSeg(segNum, segLength);
|
1362
|
+
break;
|
1363
|
+
case 62:
|
1364
|
+
readExtensionSeg(segLength);
|
1365
|
+
break;
|
1366
|
+
default:
|
1367
|
+
error(getPos(), "Unknown segment type in JBIG2 stream");
|
1368
|
+
for (i = 0; i < segLength; ++i) {
|
1369
|
+
if ((c1 = curStr->getChar()) == EOF) {
|
1370
|
+
goto eofError2;
|
1371
|
+
}
|
1372
|
+
}
|
1373
|
+
break;
|
1374
|
+
}
|
1375
|
+
|
1376
|
+
gfree(refSegs);
|
1377
|
+
}
|
1378
|
+
|
1379
|
+
return;
|
1380
|
+
|
1381
|
+
syntaxError:
|
1382
|
+
gfree(refSegs);
|
1383
|
+
return;
|
1384
|
+
|
1385
|
+
eofError2:
|
1386
|
+
gfree(refSegs);
|
1387
|
+
eofError1:
|
1388
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
1389
|
+
}
|
1390
|
+
|
1391
|
+
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
|
1392
|
+
Guint *refSegs, Guint nRefSegs) {
|
1393
|
+
JBIG2SymbolDict *symbolDict;
|
1394
|
+
JBIG2HuffmanTable *huffDHTable, *huffDWTable;
|
1395
|
+
JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
|
1396
|
+
JBIG2Segment *seg;
|
1397
|
+
GList *codeTables;
|
1398
|
+
JBIG2SymbolDict *inputSymbolDict;
|
1399
|
+
Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
|
1400
|
+
Guint huffDH, huffDW, huffBMSize, huffAggInst;
|
1401
|
+
Guint contextUsed, contextRetained;
|
1402
|
+
int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
|
1403
|
+
Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
|
1404
|
+
JBIG2Bitmap **bitmaps;
|
1405
|
+
JBIG2Bitmap *collBitmap, *refBitmap;
|
1406
|
+
Guint *symWidths;
|
1407
|
+
Guint symHeight, symWidth, totalWidth, x, symID;
|
1408
|
+
int dh, dw, refAggNum, refDX, refDY, bmSize;
|
1409
|
+
GBool ex;
|
1410
|
+
int run, cnt;
|
1411
|
+
Guint i, j, k;
|
1412
|
+
Guchar *p;
|
1413
|
+
|
1414
|
+
// symbol dictionary flags
|
1415
|
+
if (!readUWord(&flags)) {
|
1416
|
+
goto eofError;
|
1417
|
+
}
|
1418
|
+
sdTemplate = (flags >> 10) & 3;
|
1419
|
+
sdrTemplate = (flags >> 12) & 1;
|
1420
|
+
huff = flags & 1;
|
1421
|
+
refAgg = (flags >> 1) & 1;
|
1422
|
+
huffDH = (flags >> 2) & 3;
|
1423
|
+
huffDW = (flags >> 4) & 3;
|
1424
|
+
huffBMSize = (flags >> 6) & 1;
|
1425
|
+
huffAggInst = (flags >> 7) & 1;
|
1426
|
+
contextUsed = (flags >> 8) & 1;
|
1427
|
+
contextRetained = (flags >> 9) & 1;
|
1428
|
+
|
1429
|
+
// symbol dictionary AT flags
|
1430
|
+
if (!huff) {
|
1431
|
+
if (sdTemplate == 0) {
|
1432
|
+
if (!readByte(&sdATX[0]) ||
|
1433
|
+
!readByte(&sdATY[0]) ||
|
1434
|
+
!readByte(&sdATX[1]) ||
|
1435
|
+
!readByte(&sdATY[1]) ||
|
1436
|
+
!readByte(&sdATX[2]) ||
|
1437
|
+
!readByte(&sdATY[2]) ||
|
1438
|
+
!readByte(&sdATX[3]) ||
|
1439
|
+
!readByte(&sdATY[3])) {
|
1440
|
+
goto eofError;
|
1441
|
+
}
|
1442
|
+
} else {
|
1443
|
+
if (!readByte(&sdATX[0]) ||
|
1444
|
+
!readByte(&sdATY[0])) {
|
1445
|
+
goto eofError;
|
1446
|
+
}
|
1447
|
+
}
|
1448
|
+
}
|
1449
|
+
|
1450
|
+
// symbol dictionary refinement AT flags
|
1451
|
+
if (refAgg && !sdrTemplate) {
|
1452
|
+
if (!readByte(&sdrATX[0]) ||
|
1453
|
+
!readByte(&sdrATY[0]) ||
|
1454
|
+
!readByte(&sdrATX[1]) ||
|
1455
|
+
!readByte(&sdrATY[1])) {
|
1456
|
+
goto eofError;
|
1457
|
+
}
|
1458
|
+
}
|
1459
|
+
|
1460
|
+
// SDNUMEXSYMS and SDNUMNEWSYMS
|
1461
|
+
if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
|
1462
|
+
goto eofError;
|
1463
|
+
}
|
1464
|
+
|
1465
|
+
// get referenced segments: input symbol dictionaries and code tables
|
1466
|
+
codeTables = new GList();
|
1467
|
+
numInputSyms = 0;
|
1468
|
+
for (i = 0; i < nRefSegs; ++i) {
|
1469
|
+
seg = findSegment(refSegs[i]);
|
1470
|
+
if (seg->getType() == jbig2SegSymbolDict) {
|
1471
|
+
numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
|
1472
|
+
} else if (seg->getType() == jbig2SegCodeTable) {
|
1473
|
+
codeTables->append(seg);
|
1474
|
+
}
|
1475
|
+
}
|
1476
|
+
|
1477
|
+
// compute symbol code length
|
1478
|
+
symCodeLen = 0;
|
1479
|
+
i = 1;
|
1480
|
+
while (i < numInputSyms + numNewSyms) {
|
1481
|
+
++symCodeLen;
|
1482
|
+
i <<= 1;
|
1483
|
+
}
|
1484
|
+
|
1485
|
+
// get the input symbol bitmaps
|
1486
|
+
bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms,
|
1487
|
+
sizeof(JBIG2Bitmap *));
|
1488
|
+
for (i = 0; i < numInputSyms + numNewSyms; ++i) {
|
1489
|
+
bitmaps[i] = NULL;
|
1490
|
+
}
|
1491
|
+
k = 0;
|
1492
|
+
inputSymbolDict = NULL;
|
1493
|
+
for (i = 0; i < nRefSegs; ++i) {
|
1494
|
+
seg = findSegment(refSegs[i]);
|
1495
|
+
if (seg->getType() == jbig2SegSymbolDict) {
|
1496
|
+
inputSymbolDict = (JBIG2SymbolDict *)seg;
|
1497
|
+
for (j = 0; j < inputSymbolDict->getSize(); ++j) {
|
1498
|
+
bitmaps[k++] = inputSymbolDict->getBitmap(j);
|
1499
|
+
}
|
1500
|
+
}
|
1501
|
+
}
|
1502
|
+
|
1503
|
+
// get the Huffman tables
|
1504
|
+
huffDHTable = huffDWTable = NULL; // make gcc happy
|
1505
|
+
huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
|
1506
|
+
i = 0;
|
1507
|
+
if (huff) {
|
1508
|
+
if (huffDH == 0) {
|
1509
|
+
huffDHTable = huffTableD;
|
1510
|
+
} else if (huffDH == 1) {
|
1511
|
+
huffDHTable = huffTableE;
|
1512
|
+
} else {
|
1513
|
+
huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1514
|
+
}
|
1515
|
+
if (huffDW == 0) {
|
1516
|
+
huffDWTable = huffTableB;
|
1517
|
+
} else if (huffDW == 1) {
|
1518
|
+
huffDWTable = huffTableC;
|
1519
|
+
} else {
|
1520
|
+
huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1521
|
+
}
|
1522
|
+
if (huffBMSize == 0) {
|
1523
|
+
huffBMSizeTable = huffTableA;
|
1524
|
+
} else {
|
1525
|
+
huffBMSizeTable =
|
1526
|
+
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1527
|
+
}
|
1528
|
+
if (huffAggInst == 0) {
|
1529
|
+
huffAggInstTable = huffTableA;
|
1530
|
+
} else {
|
1531
|
+
huffAggInstTable =
|
1532
|
+
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1533
|
+
}
|
1534
|
+
}
|
1535
|
+
delete codeTables;
|
1536
|
+
|
1537
|
+
// set up the Huffman decoder
|
1538
|
+
if (huff) {
|
1539
|
+
huffDecoder->reset();
|
1540
|
+
|
1541
|
+
// set up the arithmetic decoder
|
1542
|
+
} else {
|
1543
|
+
if (contextUsed && inputSymbolDict) {
|
1544
|
+
resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
|
1545
|
+
} else {
|
1546
|
+
resetGenericStats(sdTemplate, NULL);
|
1547
|
+
}
|
1548
|
+
resetIntStats(symCodeLen);
|
1549
|
+
arithDecoder->start();
|
1550
|
+
}
|
1551
|
+
|
1552
|
+
// set up the arithmetic decoder for refinement/aggregation
|
1553
|
+
if (refAgg) {
|
1554
|
+
if (contextUsed && inputSymbolDict) {
|
1555
|
+
resetRefinementStats(sdrTemplate,
|
1556
|
+
inputSymbolDict->getRefinementRegionStats());
|
1557
|
+
} else {
|
1558
|
+
resetRefinementStats(sdrTemplate, NULL);
|
1559
|
+
}
|
1560
|
+
}
|
1561
|
+
|
1562
|
+
// allocate symbol widths storage
|
1563
|
+
symWidths = NULL;
|
1564
|
+
if (huff && !refAgg) {
|
1565
|
+
symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint));
|
1566
|
+
}
|
1567
|
+
|
1568
|
+
symHeight = 0;
|
1569
|
+
i = 0;
|
1570
|
+
while (i < numNewSyms) {
|
1571
|
+
|
1572
|
+
// read the height class delta height
|
1573
|
+
if (huff) {
|
1574
|
+
huffDecoder->decodeInt(&dh, huffDHTable);
|
1575
|
+
} else {
|
1576
|
+
arithDecoder->decodeInt(&dh, iadhStats);
|
1577
|
+
}
|
1578
|
+
if (dh < 0 && (Guint)-dh >= symHeight) {
|
1579
|
+
error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
|
1580
|
+
goto syntaxError;
|
1581
|
+
}
|
1582
|
+
symHeight += dh;
|
1583
|
+
symWidth = 0;
|
1584
|
+
totalWidth = 0;
|
1585
|
+
j = i;
|
1586
|
+
|
1587
|
+
// read the symbols in this height class
|
1588
|
+
while (1) {
|
1589
|
+
|
1590
|
+
// read the delta width
|
1591
|
+
if (huff) {
|
1592
|
+
if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
|
1593
|
+
break;
|
1594
|
+
}
|
1595
|
+
} else {
|
1596
|
+
if (!arithDecoder->decodeInt(&dw, iadwStats)) {
|
1597
|
+
break;
|
1598
|
+
}
|
1599
|
+
}
|
1600
|
+
if (dw < 0 && (Guint)-dw >= symWidth) {
|
1601
|
+
error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
|
1602
|
+
goto syntaxError;
|
1603
|
+
}
|
1604
|
+
symWidth += dw;
|
1605
|
+
|
1606
|
+
// using a collective bitmap, so don't read a bitmap here
|
1607
|
+
if (huff && !refAgg) {
|
1608
|
+
symWidths[i] = symWidth;
|
1609
|
+
totalWidth += symWidth;
|
1610
|
+
|
1611
|
+
// refinement/aggregate coding
|
1612
|
+
} else if (refAgg) {
|
1613
|
+
if (huff) {
|
1614
|
+
if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
|
1615
|
+
break;
|
1616
|
+
}
|
1617
|
+
} else {
|
1618
|
+
if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
|
1619
|
+
break;
|
1620
|
+
}
|
1621
|
+
}
|
1622
|
+
#if 0 //~ This special case was added about a year before the final draft
|
1623
|
+
//~ of the JBIG2 spec was released. I have encountered some old
|
1624
|
+
//~ JBIG2 images that predate it.
|
1625
|
+
if (0) {
|
1626
|
+
#else
|
1627
|
+
if (refAggNum == 1) {
|
1628
|
+
#endif
|
1629
|
+
if (huff) {
|
1630
|
+
symID = huffDecoder->readBits(symCodeLen);
|
1631
|
+
huffDecoder->decodeInt(&refDX, huffTableO);
|
1632
|
+
huffDecoder->decodeInt(&refDY, huffTableO);
|
1633
|
+
huffDecoder->decodeInt(&bmSize, huffTableA);
|
1634
|
+
huffDecoder->reset();
|
1635
|
+
arithDecoder->start();
|
1636
|
+
} else {
|
1637
|
+
symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
|
1638
|
+
arithDecoder->decodeInt(&refDX, iardxStats);
|
1639
|
+
arithDecoder->decodeInt(&refDY, iardyStats);
|
1640
|
+
}
|
1641
|
+
refBitmap = bitmaps[symID];
|
1642
|
+
bitmaps[numInputSyms + i] =
|
1643
|
+
readGenericRefinementRegion(symWidth, symHeight,
|
1644
|
+
sdrTemplate, gFalse,
|
1645
|
+
refBitmap, refDX, refDY,
|
1646
|
+
sdrATX, sdrATY);
|
1647
|
+
//~ do we need to use the bmSize value here (in Huffman mode)?
|
1648
|
+
} else {
|
1649
|
+
bitmaps[numInputSyms + i] =
|
1650
|
+
readTextRegion(huff, gTrue, symWidth, symHeight,
|
1651
|
+
refAggNum, 0, numInputSyms + i, NULL,
|
1652
|
+
symCodeLen, bitmaps, 0, 0, 0, 1, 0,
|
1653
|
+
huffTableF, huffTableH, huffTableK, huffTableO,
|
1654
|
+
huffTableO, huffTableO, huffTableO, huffTableA,
|
1655
|
+
sdrTemplate, sdrATX, sdrATY);
|
1656
|
+
}
|
1657
|
+
|
1658
|
+
// non-ref/agg coding
|
1659
|
+
} else {
|
1660
|
+
bitmaps[numInputSyms + i] =
|
1661
|
+
readGenericBitmap(gFalse, symWidth, symHeight,
|
1662
|
+
sdTemplate, gFalse, gFalse, NULL,
|
1663
|
+
sdATX, sdATY, 0);
|
1664
|
+
}
|
1665
|
+
|
1666
|
+
++i;
|
1667
|
+
}
|
1668
|
+
|
1669
|
+
// read the collective bitmap
|
1670
|
+
if (huff && !refAgg) {
|
1671
|
+
huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
|
1672
|
+
huffDecoder->reset();
|
1673
|
+
if (bmSize == 0) {
|
1674
|
+
collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
|
1675
|
+
bmSize = symHeight * ((totalWidth + 7) >> 3);
|
1676
|
+
p = collBitmap->getDataPtr();
|
1677
|
+
for (k = 0; k < (Guint)bmSize; ++k) {
|
1678
|
+
*p++ = curStr->getChar();
|
1679
|
+
}
|
1680
|
+
} else {
|
1681
|
+
collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
|
1682
|
+
0, gFalse, gFalse, NULL, NULL, NULL,
|
1683
|
+
bmSize);
|
1684
|
+
}
|
1685
|
+
x = 0;
|
1686
|
+
for (; j < i; ++j) {
|
1687
|
+
bitmaps[numInputSyms + j] =
|
1688
|
+
collBitmap->getSlice(x, 0, symWidths[j], symHeight);
|
1689
|
+
x += symWidths[j];
|
1690
|
+
}
|
1691
|
+
delete collBitmap;
|
1692
|
+
}
|
1693
|
+
}
|
1694
|
+
|
1695
|
+
// create the symbol dict object
|
1696
|
+
symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
|
1697
|
+
|
1698
|
+
// exported symbol list
|
1699
|
+
i = j = 0;
|
1700
|
+
ex = gFalse;
|
1701
|
+
while (i < numInputSyms + numNewSyms) {
|
1702
|
+
if (huff) {
|
1703
|
+
huffDecoder->decodeInt(&run, huffTableA);
|
1704
|
+
} else {
|
1705
|
+
arithDecoder->decodeInt(&run, iaexStats);
|
1706
|
+
}
|
1707
|
+
if (ex) {
|
1708
|
+
for (cnt = 0; cnt < run; ++cnt) {
|
1709
|
+
symbolDict->setBitmap(j++, bitmaps[i++]->copy());
|
1710
|
+
}
|
1711
|
+
} else {
|
1712
|
+
i += run;
|
1713
|
+
}
|
1714
|
+
ex = !ex;
|
1715
|
+
}
|
1716
|
+
|
1717
|
+
for (i = 0; i < numNewSyms; ++i) {
|
1718
|
+
delete bitmaps[numInputSyms + i];
|
1719
|
+
}
|
1720
|
+
gfree(bitmaps);
|
1721
|
+
if (symWidths) {
|
1722
|
+
gfree(symWidths);
|
1723
|
+
}
|
1724
|
+
|
1725
|
+
// save the arithmetic decoder stats
|
1726
|
+
if (!huff && contextRetained) {
|
1727
|
+
symbolDict->setGenericRegionStats(genericRegionStats->copy());
|
1728
|
+
if (refAgg) {
|
1729
|
+
symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
|
1730
|
+
}
|
1731
|
+
}
|
1732
|
+
|
1733
|
+
// store the new symbol dict
|
1734
|
+
segments->append(symbolDict);
|
1735
|
+
|
1736
|
+
return gTrue;
|
1737
|
+
|
1738
|
+
syntaxError:
|
1739
|
+
for (i = 0; i < numNewSyms; ++i) {
|
1740
|
+
if (bitmaps[numInputSyms + i]) {
|
1741
|
+
delete bitmaps[numInputSyms + i];
|
1742
|
+
}
|
1743
|
+
}
|
1744
|
+
gfree(bitmaps);
|
1745
|
+
if (symWidths) {
|
1746
|
+
gfree(symWidths);
|
1747
|
+
}
|
1748
|
+
return gFalse;
|
1749
|
+
|
1750
|
+
eofError:
|
1751
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
1752
|
+
return gFalse;
|
1753
|
+
}
|
1754
|
+
|
1755
|
+
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
|
1756
|
+
GBool lossless, Guint length,
|
1757
|
+
Guint *refSegs, Guint nRefSegs) {
|
1758
|
+
JBIG2Bitmap *bitmap;
|
1759
|
+
JBIG2HuffmanTable runLengthTab[36];
|
1760
|
+
JBIG2HuffmanTable *symCodeTab;
|
1761
|
+
JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
|
1762
|
+
JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
|
1763
|
+
JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
|
1764
|
+
JBIG2Segment *seg;
|
1765
|
+
GList *codeTables;
|
1766
|
+
JBIG2SymbolDict *symbolDict;
|
1767
|
+
JBIG2Bitmap **syms;
|
1768
|
+
Guint w, h, x, y, segInfoFlags, extCombOp;
|
1769
|
+
Guint flags, huff, refine, logStrips, refCorner, transposed;
|
1770
|
+
Guint combOp, defPixel, templ;
|
1771
|
+
int sOffset;
|
1772
|
+
Guint huffFlags, huffFS, huffDS, huffDT;
|
1773
|
+
Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
|
1774
|
+
Guint numInstances, numSyms, symCodeLen;
|
1775
|
+
int atx[2], aty[2];
|
1776
|
+
Guint i, k, kk;
|
1777
|
+
int j;
|
1778
|
+
|
1779
|
+
// region segment info field
|
1780
|
+
if (!readULong(&w) || !readULong(&h) ||
|
1781
|
+
!readULong(&x) || !readULong(&y) ||
|
1782
|
+
!readUByte(&segInfoFlags)) {
|
1783
|
+
goto eofError;
|
1784
|
+
}
|
1785
|
+
extCombOp = segInfoFlags & 7;
|
1786
|
+
|
1787
|
+
// rest of the text region header
|
1788
|
+
if (!readUWord(&flags)) {
|
1789
|
+
goto eofError;
|
1790
|
+
}
|
1791
|
+
huff = flags & 1;
|
1792
|
+
refine = (flags >> 1) & 1;
|
1793
|
+
logStrips = (flags >> 2) & 3;
|
1794
|
+
refCorner = (flags >> 4) & 3;
|
1795
|
+
transposed = (flags >> 6) & 1;
|
1796
|
+
combOp = (flags >> 7) & 3;
|
1797
|
+
defPixel = (flags >> 9) & 1;
|
1798
|
+
sOffset = (flags >> 10) & 0x1f;
|
1799
|
+
if (sOffset & 0x10) {
|
1800
|
+
sOffset |= -1 - 0x0f;
|
1801
|
+
}
|
1802
|
+
templ = (flags >> 15) & 1;
|
1803
|
+
huffFS = huffDS = huffDT = 0; // make gcc happy
|
1804
|
+
huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
|
1805
|
+
if (huff) {
|
1806
|
+
if (!readUWord(&huffFlags)) {
|
1807
|
+
goto eofError;
|
1808
|
+
}
|
1809
|
+
huffFS = huffFlags & 3;
|
1810
|
+
huffDS = (huffFlags >> 2) & 3;
|
1811
|
+
huffDT = (huffFlags >> 4) & 3;
|
1812
|
+
huffRDW = (huffFlags >> 6) & 3;
|
1813
|
+
huffRDH = (huffFlags >> 8) & 3;
|
1814
|
+
huffRDX = (huffFlags >> 10) & 3;
|
1815
|
+
huffRDY = (huffFlags >> 12) & 3;
|
1816
|
+
huffRSize = (huffFlags >> 14) & 1;
|
1817
|
+
}
|
1818
|
+
if (refine && templ == 0) {
|
1819
|
+
if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
|
1820
|
+
!readByte(&atx[1]) || !readByte(&aty[1])) {
|
1821
|
+
goto eofError;
|
1822
|
+
}
|
1823
|
+
}
|
1824
|
+
if (!readULong(&numInstances)) {
|
1825
|
+
goto eofError;
|
1826
|
+
}
|
1827
|
+
|
1828
|
+
// get symbol dictionaries and tables
|
1829
|
+
codeTables = new GList();
|
1830
|
+
numSyms = 0;
|
1831
|
+
for (i = 0; i < nRefSegs; ++i) {
|
1832
|
+
if ((seg = findSegment(refSegs[i]))) {
|
1833
|
+
if (seg->getType() == jbig2SegSymbolDict) {
|
1834
|
+
numSyms += ((JBIG2SymbolDict *)seg)->getSize();
|
1835
|
+
} else if (seg->getType() == jbig2SegCodeTable) {
|
1836
|
+
codeTables->append(seg);
|
1837
|
+
}
|
1838
|
+
} else {
|
1839
|
+
error(getPos(), "Invalid segment reference in JBIG2 text region");
|
1840
|
+
}
|
1841
|
+
}
|
1842
|
+
symCodeLen = 0;
|
1843
|
+
i = 1;
|
1844
|
+
while (i < numSyms) {
|
1845
|
+
++symCodeLen;
|
1846
|
+
i <<= 1;
|
1847
|
+
}
|
1848
|
+
|
1849
|
+
// get the symbol bitmaps
|
1850
|
+
syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
|
1851
|
+
kk = 0;
|
1852
|
+
for (i = 0; i < nRefSegs; ++i) {
|
1853
|
+
if ((seg = findSegment(refSegs[i]))) {
|
1854
|
+
if (seg->getType() == jbig2SegSymbolDict) {
|
1855
|
+
symbolDict = (JBIG2SymbolDict *)seg;
|
1856
|
+
for (k = 0; k < symbolDict->getSize(); ++k) {
|
1857
|
+
syms[kk++] = symbolDict->getBitmap(k);
|
1858
|
+
}
|
1859
|
+
}
|
1860
|
+
}
|
1861
|
+
}
|
1862
|
+
|
1863
|
+
// get the Huffman tables
|
1864
|
+
huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
|
1865
|
+
huffRDWTable = huffRDHTable = NULL; // make gcc happy
|
1866
|
+
huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
|
1867
|
+
i = 0;
|
1868
|
+
if (huff) {
|
1869
|
+
if (huffFS == 0) {
|
1870
|
+
huffFSTable = huffTableF;
|
1871
|
+
} else if (huffFS == 1) {
|
1872
|
+
huffFSTable = huffTableG;
|
1873
|
+
} else {
|
1874
|
+
huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1875
|
+
}
|
1876
|
+
if (huffDS == 0) {
|
1877
|
+
huffDSTable = huffTableH;
|
1878
|
+
} else if (huffDS == 1) {
|
1879
|
+
huffDSTable = huffTableI;
|
1880
|
+
} else if (huffDS == 2) {
|
1881
|
+
huffDSTable = huffTableJ;
|
1882
|
+
} else {
|
1883
|
+
huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1884
|
+
}
|
1885
|
+
if (huffDT == 0) {
|
1886
|
+
huffDTTable = huffTableK;
|
1887
|
+
} else if (huffDT == 1) {
|
1888
|
+
huffDTTable = huffTableL;
|
1889
|
+
} else if (huffDT == 2) {
|
1890
|
+
huffDTTable = huffTableM;
|
1891
|
+
} else {
|
1892
|
+
huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1893
|
+
}
|
1894
|
+
if (huffRDW == 0) {
|
1895
|
+
huffRDWTable = huffTableN;
|
1896
|
+
} else if (huffRDW == 1) {
|
1897
|
+
huffRDWTable = huffTableO;
|
1898
|
+
} else {
|
1899
|
+
huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1900
|
+
}
|
1901
|
+
if (huffRDH == 0) {
|
1902
|
+
huffRDHTable = huffTableN;
|
1903
|
+
} else if (huffRDH == 1) {
|
1904
|
+
huffRDHTable = huffTableO;
|
1905
|
+
} else {
|
1906
|
+
huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1907
|
+
}
|
1908
|
+
if (huffRDX == 0) {
|
1909
|
+
huffRDXTable = huffTableN;
|
1910
|
+
} else if (huffRDX == 1) {
|
1911
|
+
huffRDXTable = huffTableO;
|
1912
|
+
} else {
|
1913
|
+
huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1914
|
+
}
|
1915
|
+
if (huffRDY == 0) {
|
1916
|
+
huffRDYTable = huffTableN;
|
1917
|
+
} else if (huffRDY == 1) {
|
1918
|
+
huffRDYTable = huffTableO;
|
1919
|
+
} else {
|
1920
|
+
huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1921
|
+
}
|
1922
|
+
if (huffRSize == 0) {
|
1923
|
+
huffRSizeTable = huffTableA;
|
1924
|
+
} else {
|
1925
|
+
huffRSizeTable =
|
1926
|
+
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
|
1927
|
+
}
|
1928
|
+
}
|
1929
|
+
delete codeTables;
|
1930
|
+
|
1931
|
+
// symbol ID Huffman decoding table
|
1932
|
+
if (huff) {
|
1933
|
+
huffDecoder->reset();
|
1934
|
+
for (i = 0; i < 32; ++i) {
|
1935
|
+
runLengthTab[i].val = i;
|
1936
|
+
runLengthTab[i].prefixLen = huffDecoder->readBits(4);
|
1937
|
+
runLengthTab[i].rangeLen = 0;
|
1938
|
+
}
|
1939
|
+
runLengthTab[32].val = 0x103;
|
1940
|
+
runLengthTab[32].prefixLen = huffDecoder->readBits(4);
|
1941
|
+
runLengthTab[32].rangeLen = 2;
|
1942
|
+
runLengthTab[33].val = 0x203;
|
1943
|
+
runLengthTab[33].prefixLen = huffDecoder->readBits(4);
|
1944
|
+
runLengthTab[33].rangeLen = 3;
|
1945
|
+
runLengthTab[34].val = 0x20b;
|
1946
|
+
runLengthTab[34].prefixLen = huffDecoder->readBits(4);
|
1947
|
+
runLengthTab[34].rangeLen = 7;
|
1948
|
+
runLengthTab[35].prefixLen = 0;
|
1949
|
+
runLengthTab[35].rangeLen = jbig2HuffmanEOT;
|
1950
|
+
huffDecoder->buildTable(runLengthTab, 35);
|
1951
|
+
symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
|
1952
|
+
sizeof(JBIG2HuffmanTable));
|
1953
|
+
for (i = 0; i < numSyms; ++i) {
|
1954
|
+
symCodeTab[i].val = i;
|
1955
|
+
symCodeTab[i].rangeLen = 0;
|
1956
|
+
}
|
1957
|
+
i = 0;
|
1958
|
+
while (i < numSyms) {
|
1959
|
+
huffDecoder->decodeInt(&j, runLengthTab);
|
1960
|
+
if (j > 0x200) {
|
1961
|
+
for (j -= 0x200; j && i < numSyms; --j) {
|
1962
|
+
symCodeTab[i++].prefixLen = 0;
|
1963
|
+
}
|
1964
|
+
} else if (j > 0x100) {
|
1965
|
+
for (j -= 0x100; j && i < numSyms; --j) {
|
1966
|
+
symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
|
1967
|
+
++i;
|
1968
|
+
}
|
1969
|
+
} else {
|
1970
|
+
symCodeTab[i++].prefixLen = j;
|
1971
|
+
}
|
1972
|
+
}
|
1973
|
+
symCodeTab[numSyms].prefixLen = 0;
|
1974
|
+
symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
|
1975
|
+
huffDecoder->buildTable(symCodeTab, numSyms);
|
1976
|
+
huffDecoder->reset();
|
1977
|
+
|
1978
|
+
// set up the arithmetic decoder
|
1979
|
+
} else {
|
1980
|
+
symCodeTab = NULL;
|
1981
|
+
resetIntStats(symCodeLen);
|
1982
|
+
arithDecoder->start();
|
1983
|
+
}
|
1984
|
+
if (refine) {
|
1985
|
+
resetRefinementStats(templ, NULL);
|
1986
|
+
}
|
1987
|
+
|
1988
|
+
bitmap = readTextRegion(huff, refine, w, h, numInstances,
|
1989
|
+
logStrips, numSyms, symCodeTab, symCodeLen, syms,
|
1990
|
+
defPixel, combOp, transposed, refCorner, sOffset,
|
1991
|
+
huffFSTable, huffDSTable, huffDTTable,
|
1992
|
+
huffRDWTable, huffRDHTable,
|
1993
|
+
huffRDXTable, huffRDYTable, huffRSizeTable,
|
1994
|
+
templ, atx, aty);
|
1995
|
+
|
1996
|
+
gfree(syms);
|
1997
|
+
|
1998
|
+
// combine the region bitmap into the page bitmap
|
1999
|
+
if (imm) {
|
2000
|
+
if (pageH == 0xffffffff && y + h > curPageH) {
|
2001
|
+
pageBitmap->expand(y + h, pageDefPixel);
|
2002
|
+
}
|
2003
|
+
pageBitmap->combine(bitmap, x, y, extCombOp);
|
2004
|
+
delete bitmap;
|
2005
|
+
|
2006
|
+
// store the region bitmap
|
2007
|
+
} else {
|
2008
|
+
bitmap->setSegNum(segNum);
|
2009
|
+
segments->append(bitmap);
|
2010
|
+
}
|
2011
|
+
|
2012
|
+
// clean up the Huffman decoder
|
2013
|
+
if (huff) {
|
2014
|
+
gfree(symCodeTab);
|
2015
|
+
}
|
2016
|
+
|
2017
|
+
return;
|
2018
|
+
|
2019
|
+
eofError:
|
2020
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
2021
|
+
}
|
2022
|
+
|
2023
|
+
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
|
2024
|
+
int w, int h,
|
2025
|
+
Guint numInstances,
|
2026
|
+
Guint logStrips,
|
2027
|
+
int numSyms,
|
2028
|
+
JBIG2HuffmanTable *symCodeTab,
|
2029
|
+
Guint symCodeLen,
|
2030
|
+
JBIG2Bitmap **syms,
|
2031
|
+
Guint defPixel, Guint combOp,
|
2032
|
+
Guint transposed, Guint refCorner,
|
2033
|
+
int sOffset,
|
2034
|
+
JBIG2HuffmanTable *huffFSTable,
|
2035
|
+
JBIG2HuffmanTable *huffDSTable,
|
2036
|
+
JBIG2HuffmanTable *huffDTTable,
|
2037
|
+
JBIG2HuffmanTable *huffRDWTable,
|
2038
|
+
JBIG2HuffmanTable *huffRDHTable,
|
2039
|
+
JBIG2HuffmanTable *huffRDXTable,
|
2040
|
+
JBIG2HuffmanTable *huffRDYTable,
|
2041
|
+
JBIG2HuffmanTable *huffRSizeTable,
|
2042
|
+
Guint templ,
|
2043
|
+
int *atx, int *aty) {
|
2044
|
+
JBIG2Bitmap *bitmap;
|
2045
|
+
JBIG2Bitmap *symbolBitmap;
|
2046
|
+
Guint strips;
|
2047
|
+
int t, dt, tt, s, ds, sFirst, j;
|
2048
|
+
int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
|
2049
|
+
Guint symID, inst, bw, bh;
|
2050
|
+
|
2051
|
+
strips = 1 << logStrips;
|
2052
|
+
|
2053
|
+
// allocate the bitmap
|
2054
|
+
bitmap = new JBIG2Bitmap(0, w, h);
|
2055
|
+
if (defPixel) {
|
2056
|
+
bitmap->clearToOne();
|
2057
|
+
} else {
|
2058
|
+
bitmap->clearToZero();
|
2059
|
+
}
|
2060
|
+
|
2061
|
+
// decode initial T value
|
2062
|
+
if (huff) {
|
2063
|
+
huffDecoder->decodeInt(&t, huffDTTable);
|
2064
|
+
} else {
|
2065
|
+
arithDecoder->decodeInt(&t, iadtStats);
|
2066
|
+
}
|
2067
|
+
t *= -(int)strips;
|
2068
|
+
|
2069
|
+
inst = 0;
|
2070
|
+
sFirst = 0;
|
2071
|
+
while (inst < numInstances) {
|
2072
|
+
|
2073
|
+
// decode delta-T
|
2074
|
+
if (huff) {
|
2075
|
+
huffDecoder->decodeInt(&dt, huffDTTable);
|
2076
|
+
} else {
|
2077
|
+
arithDecoder->decodeInt(&dt, iadtStats);
|
2078
|
+
}
|
2079
|
+
t += dt * strips;
|
2080
|
+
|
2081
|
+
// first S value
|
2082
|
+
if (huff) {
|
2083
|
+
huffDecoder->decodeInt(&ds, huffFSTable);
|
2084
|
+
} else {
|
2085
|
+
arithDecoder->decodeInt(&ds, iafsStats);
|
2086
|
+
}
|
2087
|
+
sFirst += ds;
|
2088
|
+
s = sFirst;
|
2089
|
+
|
2090
|
+
// read the instances
|
2091
|
+
while (1) {
|
2092
|
+
|
2093
|
+
// T value
|
2094
|
+
if (strips == 1) {
|
2095
|
+
dt = 0;
|
2096
|
+
} else if (huff) {
|
2097
|
+
dt = huffDecoder->readBits(logStrips);
|
2098
|
+
} else {
|
2099
|
+
arithDecoder->decodeInt(&dt, iaitStats);
|
2100
|
+
}
|
2101
|
+
tt = t + dt;
|
2102
|
+
|
2103
|
+
// symbol ID
|
2104
|
+
if (huff) {
|
2105
|
+
if (symCodeTab) {
|
2106
|
+
huffDecoder->decodeInt(&j, symCodeTab);
|
2107
|
+
symID = (Guint)j;
|
2108
|
+
} else {
|
2109
|
+
symID = huffDecoder->readBits(symCodeLen);
|
2110
|
+
}
|
2111
|
+
} else {
|
2112
|
+
symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
|
2113
|
+
}
|
2114
|
+
|
2115
|
+
if (symID >= (Guint)numSyms) {
|
2116
|
+
error(getPos(), "Invalid symbol number in JBIG2 text region");
|
2117
|
+
} else {
|
2118
|
+
|
2119
|
+
// get the symbol bitmap
|
2120
|
+
symbolBitmap = NULL;
|
2121
|
+
if (refine) {
|
2122
|
+
if (huff) {
|
2123
|
+
ri = (int)huffDecoder->readBit();
|
2124
|
+
} else {
|
2125
|
+
arithDecoder->decodeInt(&ri, iariStats);
|
2126
|
+
}
|
2127
|
+
} else {
|
2128
|
+
ri = 0;
|
2129
|
+
}
|
2130
|
+
if (ri) {
|
2131
|
+
if (huff) {
|
2132
|
+
huffDecoder->decodeInt(&rdw, huffRDWTable);
|
2133
|
+
huffDecoder->decodeInt(&rdh, huffRDHTable);
|
2134
|
+
huffDecoder->decodeInt(&rdx, huffRDXTable);
|
2135
|
+
huffDecoder->decodeInt(&rdy, huffRDYTable);
|
2136
|
+
huffDecoder->decodeInt(&bmSize, huffRSizeTable);
|
2137
|
+
huffDecoder->reset();
|
2138
|
+
arithDecoder->start();
|
2139
|
+
} else {
|
2140
|
+
arithDecoder->decodeInt(&rdw, iardwStats);
|
2141
|
+
arithDecoder->decodeInt(&rdh, iardhStats);
|
2142
|
+
arithDecoder->decodeInt(&rdx, iardxStats);
|
2143
|
+
arithDecoder->decodeInt(&rdy, iardyStats);
|
2144
|
+
}
|
2145
|
+
refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
|
2146
|
+
refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
|
2147
|
+
|
2148
|
+
symbolBitmap =
|
2149
|
+
readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
|
2150
|
+
rdh + syms[symID]->getHeight(),
|
2151
|
+
templ, gFalse, syms[symID],
|
2152
|
+
refDX, refDY, atx, aty);
|
2153
|
+
//~ do we need to use the bmSize value here (in Huffman mode)?
|
2154
|
+
} else {
|
2155
|
+
symbolBitmap = syms[symID];
|
2156
|
+
}
|
2157
|
+
|
2158
|
+
// combine the symbol bitmap into the region bitmap
|
2159
|
+
//~ something is wrong here - refCorner shouldn't degenerate into
|
2160
|
+
//~ two cases
|
2161
|
+
bw = symbolBitmap->getWidth() - 1;
|
2162
|
+
bh = symbolBitmap->getHeight() - 1;
|
2163
|
+
if (transposed) {
|
2164
|
+
switch (refCorner) {
|
2165
|
+
case 0: // bottom left
|
2166
|
+
bitmap->combine(symbolBitmap, tt, s, combOp);
|
2167
|
+
break;
|
2168
|
+
case 1: // top left
|
2169
|
+
bitmap->combine(symbolBitmap, tt, s, combOp);
|
2170
|
+
break;
|
2171
|
+
case 2: // bottom right
|
2172
|
+
bitmap->combine(symbolBitmap, tt - bw, s, combOp);
|
2173
|
+
break;
|
2174
|
+
case 3: // top right
|
2175
|
+
bitmap->combine(symbolBitmap, tt - bw, s, combOp);
|
2176
|
+
break;
|
2177
|
+
}
|
2178
|
+
s += bh;
|
2179
|
+
} else {
|
2180
|
+
switch (refCorner) {
|
2181
|
+
case 0: // bottom left
|
2182
|
+
bitmap->combine(symbolBitmap, s, tt - bh, combOp);
|
2183
|
+
break;
|
2184
|
+
case 1: // top left
|
2185
|
+
bitmap->combine(symbolBitmap, s, tt, combOp);
|
2186
|
+
break;
|
2187
|
+
case 2: // bottom right
|
2188
|
+
bitmap->combine(symbolBitmap, s, tt - bh, combOp);
|
2189
|
+
break;
|
2190
|
+
case 3: // top right
|
2191
|
+
bitmap->combine(symbolBitmap, s, tt, combOp);
|
2192
|
+
break;
|
2193
|
+
}
|
2194
|
+
s += bw;
|
2195
|
+
}
|
2196
|
+
if (ri) {
|
2197
|
+
delete symbolBitmap;
|
2198
|
+
}
|
2199
|
+
}
|
2200
|
+
|
2201
|
+
// next instance
|
2202
|
+
++inst;
|
2203
|
+
|
2204
|
+
// next S value
|
2205
|
+
if (huff) {
|
2206
|
+
if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
|
2207
|
+
break;
|
2208
|
+
}
|
2209
|
+
} else {
|
2210
|
+
if (!arithDecoder->decodeInt(&ds, iadsStats)) {
|
2211
|
+
break;
|
2212
|
+
}
|
2213
|
+
}
|
2214
|
+
s += sOffset + ds;
|
2215
|
+
}
|
2216
|
+
}
|
2217
|
+
|
2218
|
+
return bitmap;
|
2219
|
+
}
|
2220
|
+
|
2221
|
+
void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
|
2222
|
+
JBIG2PatternDict *patternDict;
|
2223
|
+
JBIG2Bitmap *bitmap;
|
2224
|
+
Guint flags, patternW, patternH, grayMax, templ, mmr;
|
2225
|
+
int atx[4], aty[4];
|
2226
|
+
Guint i, x;
|
2227
|
+
|
2228
|
+
// halftone dictionary flags, pattern width and height, max gray value
|
2229
|
+
if (!readUByte(&flags) ||
|
2230
|
+
!readUByte(&patternW) ||
|
2231
|
+
!readUByte(&patternH) ||
|
2232
|
+
!readULong(&grayMax)) {
|
2233
|
+
goto eofError;
|
2234
|
+
}
|
2235
|
+
templ = (flags >> 1) & 3;
|
2236
|
+
mmr = flags & 1;
|
2237
|
+
|
2238
|
+
// set up the arithmetic decoder
|
2239
|
+
if (!mmr) {
|
2240
|
+
resetGenericStats(templ, NULL);
|
2241
|
+
arithDecoder->start();
|
2242
|
+
}
|
2243
|
+
|
2244
|
+
// read the bitmap
|
2245
|
+
atx[0] = -(int)patternW; aty[0] = 0;
|
2246
|
+
atx[1] = -3; aty[1] = -1;
|
2247
|
+
atx[2] = 2; aty[2] = -2;
|
2248
|
+
atx[3] = -2; aty[3] = -2;
|
2249
|
+
bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
|
2250
|
+
templ, gFalse, gFalse, NULL,
|
2251
|
+
atx, aty, length - 7);
|
2252
|
+
|
2253
|
+
// create the pattern dict object
|
2254
|
+
patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
|
2255
|
+
|
2256
|
+
// split up the bitmap
|
2257
|
+
x = 0;
|
2258
|
+
for (i = 0; i <= grayMax; ++i) {
|
2259
|
+
patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
|
2260
|
+
x += patternW;
|
2261
|
+
}
|
2262
|
+
|
2263
|
+
// free memory
|
2264
|
+
delete bitmap;
|
2265
|
+
|
2266
|
+
// store the new pattern dict
|
2267
|
+
segments->append(patternDict);
|
2268
|
+
|
2269
|
+
return;
|
2270
|
+
|
2271
|
+
eofError:
|
2272
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
2273
|
+
}
|
2274
|
+
|
2275
|
+
void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
|
2276
|
+
GBool lossless, Guint length,
|
2277
|
+
Guint *refSegs, Guint nRefSegs) {
|
2278
|
+
JBIG2Bitmap *bitmap;
|
2279
|
+
JBIG2Segment *seg;
|
2280
|
+
JBIG2PatternDict *patternDict;
|
2281
|
+
JBIG2Bitmap *skipBitmap;
|
2282
|
+
Guint *grayImg;
|
2283
|
+
JBIG2Bitmap *grayBitmap;
|
2284
|
+
JBIG2Bitmap *patternBitmap;
|
2285
|
+
Guint w, h, x, y, segInfoFlags, extCombOp;
|
2286
|
+
Guint flags, mmr, templ, enableSkip, combOp;
|
2287
|
+
Guint gridW, gridH, stepX, stepY, patW, patH;
|
2288
|
+
int atx[4], aty[4];
|
2289
|
+
int gridX, gridY, xx, yy, bit, j;
|
2290
|
+
Guint bpp, m, n, i;
|
2291
|
+
|
2292
|
+
// region segment info field
|
2293
|
+
if (!readULong(&w) || !readULong(&h) ||
|
2294
|
+
!readULong(&x) || !readULong(&y) ||
|
2295
|
+
!readUByte(&segInfoFlags)) {
|
2296
|
+
goto eofError;
|
2297
|
+
}
|
2298
|
+
extCombOp = segInfoFlags & 7;
|
2299
|
+
|
2300
|
+
// rest of the halftone region header
|
2301
|
+
if (!readUByte(&flags)) {
|
2302
|
+
goto eofError;
|
2303
|
+
}
|
2304
|
+
mmr = flags & 1;
|
2305
|
+
templ = (flags >> 1) & 3;
|
2306
|
+
enableSkip = (flags >> 3) & 1;
|
2307
|
+
combOp = (flags >> 4) & 7;
|
2308
|
+
if (!readULong(&gridW) || !readULong(&gridH) ||
|
2309
|
+
!readLong(&gridX) || !readLong(&gridY) ||
|
2310
|
+
!readUWord(&stepX) || !readUWord(&stepY)) {
|
2311
|
+
goto eofError;
|
2312
|
+
}
|
2313
|
+
if (w == 0 || h == 0 || w >= INT_MAX / h) {
|
2314
|
+
error(getPos(), "Bad bitmap size in JBIG2 halftone segment");
|
2315
|
+
return;
|
2316
|
+
}
|
2317
|
+
if (gridH == 0 || gridW >= INT_MAX / gridH) {
|
2318
|
+
error(getPos(), "Bad grid size in JBIG2 halftone segment");
|
2319
|
+
return;
|
2320
|
+
}
|
2321
|
+
|
2322
|
+
// get pattern dictionary
|
2323
|
+
if (nRefSegs != 1) {
|
2324
|
+
error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
|
2325
|
+
return;
|
2326
|
+
}
|
2327
|
+
seg = findSegment(refSegs[0]);
|
2328
|
+
if (seg->getType() != jbig2SegPatternDict) {
|
2329
|
+
error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
|
2330
|
+
return;
|
2331
|
+
}
|
2332
|
+
patternDict = (JBIG2PatternDict *)seg;
|
2333
|
+
bpp = 0;
|
2334
|
+
i = 1;
|
2335
|
+
while (i < patternDict->getSize()) {
|
2336
|
+
++bpp;
|
2337
|
+
i <<= 1;
|
2338
|
+
}
|
2339
|
+
patW = patternDict->getBitmap(0)->getWidth();
|
2340
|
+
patH = patternDict->getBitmap(0)->getHeight();
|
2341
|
+
|
2342
|
+
// set up the arithmetic decoder
|
2343
|
+
if (!mmr) {
|
2344
|
+
resetGenericStats(templ, NULL);
|
2345
|
+
arithDecoder->start();
|
2346
|
+
}
|
2347
|
+
|
2348
|
+
// allocate the bitmap
|
2349
|
+
bitmap = new JBIG2Bitmap(segNum, w, h);
|
2350
|
+
if (flags & 0x80) { // HDEFPIXEL
|
2351
|
+
bitmap->clearToOne();
|
2352
|
+
} else {
|
2353
|
+
bitmap->clearToZero();
|
2354
|
+
}
|
2355
|
+
|
2356
|
+
// compute the skip bitmap
|
2357
|
+
skipBitmap = NULL;
|
2358
|
+
if (enableSkip) {
|
2359
|
+
skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
|
2360
|
+
skipBitmap->clearToZero();
|
2361
|
+
for (m = 0; m < gridH; ++m) {
|
2362
|
+
for (n = 0; n < gridW; ++n) {
|
2363
|
+
xx = gridX + m * stepY + n * stepX;
|
2364
|
+
yy = gridY + m * stepX - n * stepY;
|
2365
|
+
if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
|
2366
|
+
((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
|
2367
|
+
skipBitmap->setPixel(n, m);
|
2368
|
+
}
|
2369
|
+
}
|
2370
|
+
}
|
2371
|
+
}
|
2372
|
+
|
2373
|
+
// read the gray-scale image
|
2374
|
+
grayImg = (Guint *)gmallocn(gridW * gridH, sizeof(Guint));
|
2375
|
+
memset(grayImg, 0, gridW * gridH * sizeof(Guint));
|
2376
|
+
atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1;
|
2377
|
+
atx[1] = -3; aty[1] = -1;
|
2378
|
+
atx[2] = 2; aty[2] = -2;
|
2379
|
+
atx[3] = -2; aty[3] = -2;
|
2380
|
+
for (j = bpp - 1; j >= 0; --j) {
|
2381
|
+
grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
|
2382
|
+
enableSkip, skipBitmap, atx, aty, -1);
|
2383
|
+
i = 0;
|
2384
|
+
for (m = 0; m < gridH; ++m) {
|
2385
|
+
for (n = 0; n < gridW; ++n) {
|
2386
|
+
bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
|
2387
|
+
grayImg[i] = (grayImg[i] << 1) | bit;
|
2388
|
+
++i;
|
2389
|
+
}
|
2390
|
+
}
|
2391
|
+
delete grayBitmap;
|
2392
|
+
}
|
2393
|
+
|
2394
|
+
// decode the image
|
2395
|
+
i = 0;
|
2396
|
+
for (m = 0; m < gridH; ++m) {
|
2397
|
+
xx = gridX + m * stepY;
|
2398
|
+
yy = gridY + m * stepX;
|
2399
|
+
for (n = 0; n < gridW; ++n) {
|
2400
|
+
if (!(enableSkip && skipBitmap->getPixel(n, m))) {
|
2401
|
+
patternBitmap = patternDict->getBitmap(grayImg[i]);
|
2402
|
+
bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
|
2403
|
+
}
|
2404
|
+
xx += stepX;
|
2405
|
+
yy -= stepY;
|
2406
|
+
++i;
|
2407
|
+
}
|
2408
|
+
}
|
2409
|
+
|
2410
|
+
gfree(grayImg);
|
2411
|
+
if (skipBitmap) {
|
2412
|
+
delete skipBitmap;
|
2413
|
+
}
|
2414
|
+
|
2415
|
+
// combine the region bitmap into the page bitmap
|
2416
|
+
if (imm) {
|
2417
|
+
if (pageH == 0xffffffff && y + h > curPageH) {
|
2418
|
+
pageBitmap->expand(y + h, pageDefPixel);
|
2419
|
+
}
|
2420
|
+
pageBitmap->combine(bitmap, x, y, extCombOp);
|
2421
|
+
delete bitmap;
|
2422
|
+
|
2423
|
+
// store the region bitmap
|
2424
|
+
} else {
|
2425
|
+
segments->append(bitmap);
|
2426
|
+
}
|
2427
|
+
|
2428
|
+
return;
|
2429
|
+
|
2430
|
+
eofError:
|
2431
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
2432
|
+
}
|
2433
|
+
|
2434
|
+
void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
|
2435
|
+
GBool lossless, Guint length) {
|
2436
|
+
JBIG2Bitmap *bitmap;
|
2437
|
+
Guint w, h, x, y, segInfoFlags, extCombOp;
|
2438
|
+
Guint flags, mmr, templ, tpgdOn;
|
2439
|
+
int atx[4], aty[4];
|
2440
|
+
|
2441
|
+
// region segment info field
|
2442
|
+
if (!readULong(&w) || !readULong(&h) ||
|
2443
|
+
!readULong(&x) || !readULong(&y) ||
|
2444
|
+
!readUByte(&segInfoFlags)) {
|
2445
|
+
goto eofError;
|
2446
|
+
}
|
2447
|
+
extCombOp = segInfoFlags & 7;
|
2448
|
+
|
2449
|
+
// rest of the generic region segment header
|
2450
|
+
if (!readUByte(&flags)) {
|
2451
|
+
goto eofError;
|
2452
|
+
}
|
2453
|
+
mmr = flags & 1;
|
2454
|
+
templ = (flags >> 1) & 3;
|
2455
|
+
tpgdOn = (flags >> 3) & 1;
|
2456
|
+
|
2457
|
+
// AT flags
|
2458
|
+
if (!mmr) {
|
2459
|
+
if (templ == 0) {
|
2460
|
+
if (!readByte(&atx[0]) ||
|
2461
|
+
!readByte(&aty[0]) ||
|
2462
|
+
!readByte(&atx[1]) ||
|
2463
|
+
!readByte(&aty[1]) ||
|
2464
|
+
!readByte(&atx[2]) ||
|
2465
|
+
!readByte(&aty[2]) ||
|
2466
|
+
!readByte(&atx[3]) ||
|
2467
|
+
!readByte(&aty[3])) {
|
2468
|
+
goto eofError;
|
2469
|
+
}
|
2470
|
+
} else {
|
2471
|
+
if (!readByte(&atx[0]) ||
|
2472
|
+
!readByte(&aty[0])) {
|
2473
|
+
goto eofError;
|
2474
|
+
}
|
2475
|
+
}
|
2476
|
+
}
|
2477
|
+
|
2478
|
+
// set up the arithmetic decoder
|
2479
|
+
if (!mmr) {
|
2480
|
+
resetGenericStats(templ, NULL);
|
2481
|
+
arithDecoder->start();
|
2482
|
+
}
|
2483
|
+
|
2484
|
+
// read the bitmap
|
2485
|
+
bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
|
2486
|
+
NULL, atx, aty, mmr ? 0 : length - 18);
|
2487
|
+
|
2488
|
+
// combine the region bitmap into the page bitmap
|
2489
|
+
if (imm) {
|
2490
|
+
if (pageH == 0xffffffff && y + h > curPageH) {
|
2491
|
+
pageBitmap->expand(y + h, pageDefPixel);
|
2492
|
+
}
|
2493
|
+
pageBitmap->combine(bitmap, x, y, extCombOp);
|
2494
|
+
delete bitmap;
|
2495
|
+
|
2496
|
+
// store the region bitmap
|
2497
|
+
} else {
|
2498
|
+
bitmap->setSegNum(segNum);
|
2499
|
+
segments->append(bitmap);
|
2500
|
+
}
|
2501
|
+
|
2502
|
+
return;
|
2503
|
+
|
2504
|
+
eofError:
|
2505
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
2506
|
+
}
|
2507
|
+
|
2508
|
+
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
|
2509
|
+
int templ, GBool tpgdOn,
|
2510
|
+
GBool useSkip, JBIG2Bitmap *skip,
|
2511
|
+
int *atx, int *aty,
|
2512
|
+
int mmrDataLength) {
|
2513
|
+
JBIG2Bitmap *bitmap;
|
2514
|
+
GBool ltp;
|
2515
|
+
Guint ltpCX, cx, cx0, cx1, cx2;
|
2516
|
+
JBIG2BitmapPtr cxPtr0, cxPtr1;
|
2517
|
+
JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
|
2518
|
+
int *refLine, *codingLine;
|
2519
|
+
int code1, code2, code3;
|
2520
|
+
int x, y, a0, pix, i, refI, codingI;
|
2521
|
+
|
2522
|
+
bitmap = new JBIG2Bitmap(0, w, h);
|
2523
|
+
bitmap->clearToZero();
|
2524
|
+
|
2525
|
+
//----- MMR decode
|
2526
|
+
|
2527
|
+
if (mmr) {
|
2528
|
+
|
2529
|
+
mmrDecoder->reset();
|
2530
|
+
refLine = (int *)gmallocn(w + 2, sizeof(int));
|
2531
|
+
codingLine = (int *)gmallocn(w + 2, sizeof(int));
|
2532
|
+
codingLine[0] = codingLine[1] = w;
|
2533
|
+
|
2534
|
+
for (y = 0; y < h; ++y) {
|
2535
|
+
|
2536
|
+
// copy coding line to ref line
|
2537
|
+
for (i = 0; codingLine[i] < w; ++i) {
|
2538
|
+
refLine[i] = codingLine[i];
|
2539
|
+
}
|
2540
|
+
refLine[i] = refLine[i + 1] = w;
|
2541
|
+
|
2542
|
+
// decode a line
|
2543
|
+
refI = 0; // b1 = refLine[refI]
|
2544
|
+
codingI = 0; // a1 = codingLine[codingI]
|
2545
|
+
a0 = 0;
|
2546
|
+
do {
|
2547
|
+
code1 = mmrDecoder->get2DCode();
|
2548
|
+
switch (code1) {
|
2549
|
+
case twoDimPass:
|
2550
|
+
if (refLine[refI] < w) {
|
2551
|
+
a0 = refLine[refI + 1];
|
2552
|
+
refI += 2;
|
2553
|
+
}
|
2554
|
+
break;
|
2555
|
+
case twoDimHoriz:
|
2556
|
+
if (codingI & 1) {
|
2557
|
+
code1 = 0;
|
2558
|
+
do {
|
2559
|
+
code1 += code3 = mmrDecoder->getBlackCode();
|
2560
|
+
} while (code3 >= 64);
|
2561
|
+
code2 = 0;
|
2562
|
+
do {
|
2563
|
+
code2 += code3 = mmrDecoder->getWhiteCode();
|
2564
|
+
} while (code3 >= 64);
|
2565
|
+
} else {
|
2566
|
+
code1 = 0;
|
2567
|
+
do {
|
2568
|
+
code1 += code3 = mmrDecoder->getWhiteCode();
|
2569
|
+
} while (code3 >= 64);
|
2570
|
+
code2 = 0;
|
2571
|
+
do {
|
2572
|
+
code2 += code3 = mmrDecoder->getBlackCode();
|
2573
|
+
} while (code3 >= 64);
|
2574
|
+
}
|
2575
|
+
if (code1 > 0 || code2 > 0) {
|
2576
|
+
a0 = codingLine[codingI++] = a0 + code1;
|
2577
|
+
a0 = codingLine[codingI++] = a0 + code2;
|
2578
|
+
while (refLine[refI] <= a0 && refLine[refI] < w) {
|
2579
|
+
refI += 2;
|
2580
|
+
}
|
2581
|
+
}
|
2582
|
+
break;
|
2583
|
+
case twoDimVert0:
|
2584
|
+
a0 = codingLine[codingI++] = refLine[refI];
|
2585
|
+
if (refLine[refI] < w) {
|
2586
|
+
++refI;
|
2587
|
+
}
|
2588
|
+
break;
|
2589
|
+
case twoDimVertR1:
|
2590
|
+
a0 = codingLine[codingI++] = refLine[refI] + 1;
|
2591
|
+
if (refLine[refI] < w) {
|
2592
|
+
++refI;
|
2593
|
+
while (refLine[refI] <= a0 && refLine[refI] < w) {
|
2594
|
+
refI += 2;
|
2595
|
+
}
|
2596
|
+
}
|
2597
|
+
break;
|
2598
|
+
case twoDimVertR2:
|
2599
|
+
a0 = codingLine[codingI++] = refLine[refI] + 2;
|
2600
|
+
if (refLine[refI] < w) {
|
2601
|
+
++refI;
|
2602
|
+
while (refLine[refI] <= a0 && refLine[refI] < w) {
|
2603
|
+
refI += 2;
|
2604
|
+
}
|
2605
|
+
}
|
2606
|
+
break;
|
2607
|
+
case twoDimVertR3:
|
2608
|
+
a0 = codingLine[codingI++] = refLine[refI] + 3;
|
2609
|
+
if (refLine[refI] < w) {
|
2610
|
+
++refI;
|
2611
|
+
while (refLine[refI] <= a0 && refLine[refI] < w) {
|
2612
|
+
refI += 2;
|
2613
|
+
}
|
2614
|
+
}
|
2615
|
+
break;
|
2616
|
+
case twoDimVertL1:
|
2617
|
+
a0 = codingLine[codingI++] = refLine[refI] - 1;
|
2618
|
+
if (refI > 0) {
|
2619
|
+
--refI;
|
2620
|
+
} else {
|
2621
|
+
++refI;
|
2622
|
+
}
|
2623
|
+
while (refLine[refI] <= a0 && refLine[refI] < w) {
|
2624
|
+
refI += 2;
|
2625
|
+
}
|
2626
|
+
break;
|
2627
|
+
case twoDimVertL2:
|
2628
|
+
a0 = codingLine[codingI++] = refLine[refI] - 2;
|
2629
|
+
if (refI > 0) {
|
2630
|
+
--refI;
|
2631
|
+
} else {
|
2632
|
+
++refI;
|
2633
|
+
}
|
2634
|
+
while (refLine[refI] <= a0 && refLine[refI] < w) {
|
2635
|
+
refI += 2;
|
2636
|
+
}
|
2637
|
+
break;
|
2638
|
+
case twoDimVertL3:
|
2639
|
+
a0 = codingLine[codingI++] = refLine[refI] - 3;
|
2640
|
+
if (refI > 0) {
|
2641
|
+
--refI;
|
2642
|
+
} else {
|
2643
|
+
++refI;
|
2644
|
+
}
|
2645
|
+
while (refLine[refI] <= a0 && refLine[refI] < w) {
|
2646
|
+
refI += 2;
|
2647
|
+
}
|
2648
|
+
break;
|
2649
|
+
default:
|
2650
|
+
error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
|
2651
|
+
break;
|
2652
|
+
}
|
2653
|
+
} while (a0 < w);
|
2654
|
+
codingLine[codingI++] = w;
|
2655
|
+
|
2656
|
+
// convert the run lengths to a bitmap line
|
2657
|
+
i = 0;
|
2658
|
+
while (codingLine[i] < w) {
|
2659
|
+
for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
|
2660
|
+
bitmap->setPixel(x, y);
|
2661
|
+
}
|
2662
|
+
i += 2;
|
2663
|
+
}
|
2664
|
+
}
|
2665
|
+
|
2666
|
+
if (mmrDataLength >= 0) {
|
2667
|
+
mmrDecoder->skipTo(mmrDataLength);
|
2668
|
+
} else {
|
2669
|
+
if (mmrDecoder->get24Bits() != 0x001001) {
|
2670
|
+
error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
|
2671
|
+
}
|
2672
|
+
}
|
2673
|
+
|
2674
|
+
gfree(refLine);
|
2675
|
+
gfree(codingLine);
|
2676
|
+
|
2677
|
+
//----- arithmetic decode
|
2678
|
+
|
2679
|
+
} else {
|
2680
|
+
// set up the typical row context
|
2681
|
+
ltpCX = 0; // make gcc happy
|
2682
|
+
if (tpgdOn) {
|
2683
|
+
switch (templ) {
|
2684
|
+
case 0:
|
2685
|
+
ltpCX = 0x3953; // 001 11001 0101 0011
|
2686
|
+
break;
|
2687
|
+
case 1:
|
2688
|
+
ltpCX = 0x079a; // 0011 11001 101 0
|
2689
|
+
break;
|
2690
|
+
case 2:
|
2691
|
+
ltpCX = 0x0e3; // 001 1100 01 1
|
2692
|
+
break;
|
2693
|
+
case 3:
|
2694
|
+
ltpCX = 0x18a; // 01100 0101 1
|
2695
|
+
break;
|
2696
|
+
}
|
2697
|
+
}
|
2698
|
+
|
2699
|
+
ltp = 0;
|
2700
|
+
cx = cx0 = cx1 = cx2 = 0; // make gcc happy
|
2701
|
+
for (y = 0; y < h; ++y) {
|
2702
|
+
|
2703
|
+
// check for a "typical" (duplicate) row
|
2704
|
+
if (tpgdOn) {
|
2705
|
+
if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
|
2706
|
+
ltp = !ltp;
|
2707
|
+
}
|
2708
|
+
if (ltp) {
|
2709
|
+
bitmap->duplicateRow(y, y-1);
|
2710
|
+
continue;
|
2711
|
+
}
|
2712
|
+
}
|
2713
|
+
|
2714
|
+
switch (templ) {
|
2715
|
+
case 0:
|
2716
|
+
|
2717
|
+
// set up the context
|
2718
|
+
bitmap->getPixelPtr(0, y-2, &cxPtr0);
|
2719
|
+
cx0 = bitmap->nextPixel(&cxPtr0);
|
2720
|
+
cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
|
2721
|
+
bitmap->getPixelPtr(0, y-1, &cxPtr1);
|
2722
|
+
cx1 = bitmap->nextPixel(&cxPtr1);
|
2723
|
+
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
|
2724
|
+
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
|
2725
|
+
cx2 = 0;
|
2726
|
+
bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
|
2727
|
+
bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1);
|
2728
|
+
bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2);
|
2729
|
+
bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3);
|
2730
|
+
|
2731
|
+
// decode the row
|
2732
|
+
for (x = 0; x < w; ++x) {
|
2733
|
+
|
2734
|
+
// build the context
|
2735
|
+
cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
|
2736
|
+
(bitmap->nextPixel(&atPtr0) << 3) |
|
2737
|
+
(bitmap->nextPixel(&atPtr1) << 2) |
|
2738
|
+
(bitmap->nextPixel(&atPtr2) << 1) |
|
2739
|
+
bitmap->nextPixel(&atPtr3);
|
2740
|
+
|
2741
|
+
// check for a skipped pixel
|
2742
|
+
if (useSkip && skip->getPixel(x, y)) {
|
2743
|
+
pix = 0;
|
2744
|
+
|
2745
|
+
// decode the pixel
|
2746
|
+
} else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
|
2747
|
+
bitmap->setPixel(x, y);
|
2748
|
+
}
|
2749
|
+
|
2750
|
+
// update the context
|
2751
|
+
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
|
2752
|
+
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
|
2753
|
+
cx2 = ((cx2 << 1) | pix) & 0x0f;
|
2754
|
+
}
|
2755
|
+
break;
|
2756
|
+
|
2757
|
+
case 1:
|
2758
|
+
|
2759
|
+
// set up the context
|
2760
|
+
bitmap->getPixelPtr(0, y-2, &cxPtr0);
|
2761
|
+
cx0 = bitmap->nextPixel(&cxPtr0);
|
2762
|
+
cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
|
2763
|
+
cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
|
2764
|
+
bitmap->getPixelPtr(0, y-1, &cxPtr1);
|
2765
|
+
cx1 = bitmap->nextPixel(&cxPtr1);
|
2766
|
+
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
|
2767
|
+
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
|
2768
|
+
cx2 = 0;
|
2769
|
+
bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
|
2770
|
+
|
2771
|
+
// decode the row
|
2772
|
+
for (x = 0; x < w; ++x) {
|
2773
|
+
|
2774
|
+
// build the context
|
2775
|
+
cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
|
2776
|
+
bitmap->nextPixel(&atPtr0);
|
2777
|
+
|
2778
|
+
// check for a skipped pixel
|
2779
|
+
if (useSkip && skip->getPixel(x, y)) {
|
2780
|
+
pix = 0;
|
2781
|
+
|
2782
|
+
// decode the pixel
|
2783
|
+
} else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
|
2784
|
+
bitmap->setPixel(x, y);
|
2785
|
+
}
|
2786
|
+
|
2787
|
+
// update the context
|
2788
|
+
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
|
2789
|
+
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
|
2790
|
+
cx2 = ((cx2 << 1) | pix) & 0x07;
|
2791
|
+
}
|
2792
|
+
break;
|
2793
|
+
|
2794
|
+
case 2:
|
2795
|
+
|
2796
|
+
// set up the context
|
2797
|
+
bitmap->getPixelPtr(0, y-2, &cxPtr0);
|
2798
|
+
cx0 = bitmap->nextPixel(&cxPtr0);
|
2799
|
+
cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
|
2800
|
+
bitmap->getPixelPtr(0, y-1, &cxPtr1);
|
2801
|
+
cx1 = bitmap->nextPixel(&cxPtr1);
|
2802
|
+
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
|
2803
|
+
cx2 = 0;
|
2804
|
+
bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
|
2805
|
+
|
2806
|
+
// decode the row
|
2807
|
+
for (x = 0; x < w; ++x) {
|
2808
|
+
|
2809
|
+
// build the context
|
2810
|
+
cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
|
2811
|
+
bitmap->nextPixel(&atPtr0);
|
2812
|
+
|
2813
|
+
// check for a skipped pixel
|
2814
|
+
if (useSkip && skip->getPixel(x, y)) {
|
2815
|
+
pix = 0;
|
2816
|
+
|
2817
|
+
// decode the pixel
|
2818
|
+
} else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
|
2819
|
+
bitmap->setPixel(x, y);
|
2820
|
+
}
|
2821
|
+
|
2822
|
+
// update the context
|
2823
|
+
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
|
2824
|
+
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f;
|
2825
|
+
cx2 = ((cx2 << 1) | pix) & 0x03;
|
2826
|
+
}
|
2827
|
+
break;
|
2828
|
+
|
2829
|
+
case 3:
|
2830
|
+
|
2831
|
+
// set up the context
|
2832
|
+
bitmap->getPixelPtr(0, y-1, &cxPtr1);
|
2833
|
+
cx1 = bitmap->nextPixel(&cxPtr1);
|
2834
|
+
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
|
2835
|
+
cx2 = 0;
|
2836
|
+
bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
|
2837
|
+
|
2838
|
+
// decode the row
|
2839
|
+
for (x = 0; x < w; ++x) {
|
2840
|
+
|
2841
|
+
// build the context
|
2842
|
+
cx = (cx1 << 5) | (cx2 << 1) |
|
2843
|
+
bitmap->nextPixel(&atPtr0);
|
2844
|
+
|
2845
|
+
// check for a skipped pixel
|
2846
|
+
if (useSkip && skip->getPixel(x, y)) {
|
2847
|
+
pix = 0;
|
2848
|
+
|
2849
|
+
// decode the pixel
|
2850
|
+
} else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
|
2851
|
+
bitmap->setPixel(x, y);
|
2852
|
+
}
|
2853
|
+
|
2854
|
+
// update the context
|
2855
|
+
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
|
2856
|
+
cx2 = ((cx2 << 1) | pix) & 0x0f;
|
2857
|
+
}
|
2858
|
+
break;
|
2859
|
+
}
|
2860
|
+
}
|
2861
|
+
}
|
2862
|
+
|
2863
|
+
return bitmap;
|
2864
|
+
}
|
2865
|
+
|
2866
|
+
void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
|
2867
|
+
GBool lossless, Guint length,
|
2868
|
+
Guint *refSegs,
|
2869
|
+
Guint nRefSegs) {
|
2870
|
+
JBIG2Bitmap *bitmap, *refBitmap;
|
2871
|
+
Guint w, h, x, y, segInfoFlags, extCombOp;
|
2872
|
+
Guint flags, templ, tpgrOn;
|
2873
|
+
int atx[2], aty[2];
|
2874
|
+
JBIG2Segment *seg;
|
2875
|
+
|
2876
|
+
// region segment info field
|
2877
|
+
if (!readULong(&w) || !readULong(&h) ||
|
2878
|
+
!readULong(&x) || !readULong(&y) ||
|
2879
|
+
!readUByte(&segInfoFlags)) {
|
2880
|
+
goto eofError;
|
2881
|
+
}
|
2882
|
+
extCombOp = segInfoFlags & 7;
|
2883
|
+
|
2884
|
+
// rest of the generic refinement region segment header
|
2885
|
+
if (!readUByte(&flags)) {
|
2886
|
+
goto eofError;
|
2887
|
+
}
|
2888
|
+
templ = flags & 1;
|
2889
|
+
tpgrOn = (flags >> 1) & 1;
|
2890
|
+
|
2891
|
+
// AT flags
|
2892
|
+
if (!templ) {
|
2893
|
+
if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
|
2894
|
+
!readByte(&atx[1]) || !readByte(&aty[1])) {
|
2895
|
+
goto eofError;
|
2896
|
+
}
|
2897
|
+
}
|
2898
|
+
|
2899
|
+
// resize the page bitmap if needed
|
2900
|
+
if (nRefSegs == 0 || imm) {
|
2901
|
+
if (pageH == 0xffffffff && y + h > curPageH) {
|
2902
|
+
pageBitmap->expand(y + h, pageDefPixel);
|
2903
|
+
}
|
2904
|
+
}
|
2905
|
+
|
2906
|
+
// get referenced bitmap
|
2907
|
+
if (nRefSegs > 1) {
|
2908
|
+
error(getPos(), "Bad reference in JBIG2 generic refinement segment");
|
2909
|
+
return;
|
2910
|
+
}
|
2911
|
+
if (nRefSegs == 1) {
|
2912
|
+
seg = findSegment(refSegs[0]);
|
2913
|
+
if (seg->getType() != jbig2SegBitmap) {
|
2914
|
+
error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
|
2915
|
+
return;
|
2916
|
+
}
|
2917
|
+
refBitmap = (JBIG2Bitmap *)seg;
|
2918
|
+
} else {
|
2919
|
+
refBitmap = pageBitmap->getSlice(x, y, w, h);
|
2920
|
+
}
|
2921
|
+
|
2922
|
+
// set up the arithmetic decoder
|
2923
|
+
resetRefinementStats(templ, NULL);
|
2924
|
+
arithDecoder->start();
|
2925
|
+
|
2926
|
+
// read
|
2927
|
+
bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
|
2928
|
+
refBitmap, 0, 0, atx, aty);
|
2929
|
+
|
2930
|
+
// combine the region bitmap into the page bitmap
|
2931
|
+
if (imm) {
|
2932
|
+
pageBitmap->combine(bitmap, x, y, extCombOp);
|
2933
|
+
delete bitmap;
|
2934
|
+
|
2935
|
+
// store the region bitmap
|
2936
|
+
} else {
|
2937
|
+
bitmap->setSegNum(segNum);
|
2938
|
+
segments->append(bitmap);
|
2939
|
+
}
|
2940
|
+
|
2941
|
+
// delete the referenced bitmap
|
2942
|
+
if (nRefSegs == 1) {
|
2943
|
+
discardSegment(refSegs[0]);
|
2944
|
+
} else {
|
2945
|
+
delete refBitmap;
|
2946
|
+
}
|
2947
|
+
|
2948
|
+
return;
|
2949
|
+
|
2950
|
+
eofError:
|
2951
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
2952
|
+
}
|
2953
|
+
|
2954
|
+
JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
|
2955
|
+
int templ, GBool tpgrOn,
|
2956
|
+
JBIG2Bitmap *refBitmap,
|
2957
|
+
int refDX, int refDY,
|
2958
|
+
int *atx, int *aty) {
|
2959
|
+
JBIG2Bitmap *bitmap;
|
2960
|
+
GBool ltp;
|
2961
|
+
Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
|
2962
|
+
JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
|
2963
|
+
JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
|
2964
|
+
int x, y, pix;
|
2965
|
+
|
2966
|
+
bitmap = new JBIG2Bitmap(0, w, h);
|
2967
|
+
bitmap->clearToZero();
|
2968
|
+
|
2969
|
+
// set up the typical row context
|
2970
|
+
if (templ) {
|
2971
|
+
ltpCX = 0x008;
|
2972
|
+
} else {
|
2973
|
+
ltpCX = 0x0010;
|
2974
|
+
}
|
2975
|
+
|
2976
|
+
ltp = 0;
|
2977
|
+
for (y = 0; y < h; ++y) {
|
2978
|
+
|
2979
|
+
if (templ) {
|
2980
|
+
|
2981
|
+
// set up the context
|
2982
|
+
bitmap->getPixelPtr(0, y-1, &cxPtr0);
|
2983
|
+
cx0 = bitmap->nextPixel(&cxPtr0);
|
2984
|
+
bitmap->getPixelPtr(-1, y, &cxPtr1);
|
2985
|
+
refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
|
2986
|
+
refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
|
2987
|
+
cx3 = refBitmap->nextPixel(&cxPtr3);
|
2988
|
+
cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
|
2989
|
+
refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
|
2990
|
+
cx4 = refBitmap->nextPixel(&cxPtr4);
|
2991
|
+
|
2992
|
+
// set up the typical prediction context
|
2993
|
+
tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
|
2994
|
+
if (tpgrOn) {
|
2995
|
+
refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
|
2996
|
+
tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
|
2997
|
+
tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
|
2998
|
+
tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
|
2999
|
+
refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
|
3000
|
+
tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
|
3001
|
+
tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
|
3002
|
+
tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
|
3003
|
+
refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
|
3004
|
+
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
|
3005
|
+
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
|
3006
|
+
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
|
3007
|
+
}
|
3008
|
+
|
3009
|
+
for (x = 0; x < w; ++x) {
|
3010
|
+
|
3011
|
+
// update the context
|
3012
|
+
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
|
3013
|
+
cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
|
3014
|
+
cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
|
3015
|
+
|
3016
|
+
if (tpgrOn) {
|
3017
|
+
// update the typical predictor context
|
3018
|
+
tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
|
3019
|
+
tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
|
3020
|
+
tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
|
3021
|
+
|
3022
|
+
// check for a "typical" pixel
|
3023
|
+
if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
|
3024
|
+
ltp = !ltp;
|
3025
|
+
}
|
3026
|
+
if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
|
3027
|
+
bitmap->clearPixel(x, y);
|
3028
|
+
continue;
|
3029
|
+
} else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
|
3030
|
+
bitmap->setPixel(x, y);
|
3031
|
+
continue;
|
3032
|
+
}
|
3033
|
+
}
|
3034
|
+
|
3035
|
+
// build the context
|
3036
|
+
cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
|
3037
|
+
(refBitmap->nextPixel(&cxPtr2) << 5) |
|
3038
|
+
(cx3 << 2) | cx4;
|
3039
|
+
|
3040
|
+
// decode the pixel
|
3041
|
+
if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
|
3042
|
+
bitmap->setPixel(x, y);
|
3043
|
+
}
|
3044
|
+
}
|
3045
|
+
|
3046
|
+
} else {
|
3047
|
+
|
3048
|
+
// set up the context
|
3049
|
+
bitmap->getPixelPtr(0, y-1, &cxPtr0);
|
3050
|
+
cx0 = bitmap->nextPixel(&cxPtr0);
|
3051
|
+
bitmap->getPixelPtr(-1, y, &cxPtr1);
|
3052
|
+
refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
|
3053
|
+
cx2 = refBitmap->nextPixel(&cxPtr2);
|
3054
|
+
refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
|
3055
|
+
cx3 = refBitmap->nextPixel(&cxPtr3);
|
3056
|
+
cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
|
3057
|
+
refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
|
3058
|
+
cx4 = refBitmap->nextPixel(&cxPtr4);
|
3059
|
+
cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
|
3060
|
+
bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
|
3061
|
+
refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);
|
3062
|
+
|
3063
|
+
// set up the typical prediction context
|
3064
|
+
tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
|
3065
|
+
if (tpgrOn) {
|
3066
|
+
refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
|
3067
|
+
tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
|
3068
|
+
tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
|
3069
|
+
tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
|
3070
|
+
refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
|
3071
|
+
tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
|
3072
|
+
tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
|
3073
|
+
tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
|
3074
|
+
refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
|
3075
|
+
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
|
3076
|
+
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
|
3077
|
+
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
|
3078
|
+
}
|
3079
|
+
|
3080
|
+
for (x = 0; x < w; ++x) {
|
3081
|
+
|
3082
|
+
// update the context
|
3083
|
+
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
|
3084
|
+
cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
|
3085
|
+
cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
|
3086
|
+
cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;
|
3087
|
+
|
3088
|
+
if (tpgrOn) {
|
3089
|
+
// update the typical predictor context
|
3090
|
+
tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
|
3091
|
+
tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
|
3092
|
+
tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
|
3093
|
+
|
3094
|
+
// check for a "typical" pixel
|
3095
|
+
if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
|
3096
|
+
ltp = !ltp;
|
3097
|
+
}
|
3098
|
+
if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
|
3099
|
+
bitmap->clearPixel(x, y);
|
3100
|
+
continue;
|
3101
|
+
} else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
|
3102
|
+
bitmap->setPixel(x, y);
|
3103
|
+
continue;
|
3104
|
+
}
|
3105
|
+
}
|
3106
|
+
|
3107
|
+
// build the context
|
3108
|
+
cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
|
3109
|
+
(cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
|
3110
|
+
(bitmap->nextPixel(&cxPtr5) << 1) |
|
3111
|
+
refBitmap->nextPixel(&cxPtr6);
|
3112
|
+
|
3113
|
+
// decode the pixel
|
3114
|
+
if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
|
3115
|
+
bitmap->setPixel(x, y);
|
3116
|
+
}
|
3117
|
+
}
|
3118
|
+
}
|
3119
|
+
}
|
3120
|
+
|
3121
|
+
return bitmap;
|
3122
|
+
}
|
3123
|
+
|
3124
|
+
void JBIG2Stream::readPageInfoSeg(Guint length) {
|
3125
|
+
Guint xRes, yRes, flags, striping;
|
3126
|
+
|
3127
|
+
if (!readULong(&pageW) || !readULong(&pageH) ||
|
3128
|
+
!readULong(&xRes) || !readULong(&yRes) ||
|
3129
|
+
!readUByte(&flags) || !readUWord(&striping)) {
|
3130
|
+
goto eofError;
|
3131
|
+
}
|
3132
|
+
pageDefPixel = (flags >> 2) & 1;
|
3133
|
+
defCombOp = (flags >> 3) & 3;
|
3134
|
+
|
3135
|
+
// allocate the page bitmap
|
3136
|
+
if (pageH == 0xffffffff) {
|
3137
|
+
curPageH = striping & 0x7fff;
|
3138
|
+
} else {
|
3139
|
+
curPageH = pageH;
|
3140
|
+
}
|
3141
|
+
pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
|
3142
|
+
|
3143
|
+
// default pixel value
|
3144
|
+
if (pageDefPixel) {
|
3145
|
+
pageBitmap->clearToOne();
|
3146
|
+
} else {
|
3147
|
+
pageBitmap->clearToZero();
|
3148
|
+
}
|
3149
|
+
|
3150
|
+
return;
|
3151
|
+
|
3152
|
+
eofError:
|
3153
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
3154
|
+
}
|
3155
|
+
|
3156
|
+
void JBIG2Stream::readEndOfStripeSeg(Guint length) {
|
3157
|
+
Guint i;
|
3158
|
+
|
3159
|
+
// skip the segment
|
3160
|
+
for (i = 0; i < length; ++i) {
|
3161
|
+
curStr->getChar();
|
3162
|
+
}
|
3163
|
+
}
|
3164
|
+
|
3165
|
+
void JBIG2Stream::readProfilesSeg(Guint length) {
|
3166
|
+
Guint i;
|
3167
|
+
|
3168
|
+
// skip the segment
|
3169
|
+
for (i = 0; i < length; ++i) {
|
3170
|
+
curStr->getChar();
|
3171
|
+
}
|
3172
|
+
}
|
3173
|
+
|
3174
|
+
void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
|
3175
|
+
JBIG2HuffmanTable *huffTab;
|
3176
|
+
Guint flags, oob, prefixBits, rangeBits;
|
3177
|
+
int lowVal, highVal, val;
|
3178
|
+
Guint huffTabSize, i;
|
3179
|
+
|
3180
|
+
if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
|
3181
|
+
goto eofError;
|
3182
|
+
}
|
3183
|
+
oob = flags & 1;
|
3184
|
+
prefixBits = ((flags >> 1) & 7) + 1;
|
3185
|
+
rangeBits = ((flags >> 4) & 7) + 1;
|
3186
|
+
|
3187
|
+
huffDecoder->reset();
|
3188
|
+
huffTabSize = 8;
|
3189
|
+
huffTab = (JBIG2HuffmanTable *)
|
3190
|
+
gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable));
|
3191
|
+
i = 0;
|
3192
|
+
val = lowVal;
|
3193
|
+
while (val < highVal) {
|
3194
|
+
if (i == huffTabSize) {
|
3195
|
+
huffTabSize *= 2;
|
3196
|
+
huffTab = (JBIG2HuffmanTable *)
|
3197
|
+
greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
|
3198
|
+
}
|
3199
|
+
huffTab[i].val = val;
|
3200
|
+
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
|
3201
|
+
huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
|
3202
|
+
val += 1 << huffTab[i].rangeLen;
|
3203
|
+
++i;
|
3204
|
+
}
|
3205
|
+
if (i + oob + 3 > huffTabSize) {
|
3206
|
+
huffTabSize = i + oob + 3;
|
3207
|
+
huffTab = (JBIG2HuffmanTable *)
|
3208
|
+
greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
|
3209
|
+
}
|
3210
|
+
huffTab[i].val = lowVal - 1;
|
3211
|
+
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
|
3212
|
+
huffTab[i].rangeLen = jbig2HuffmanLOW;
|
3213
|
+
++i;
|
3214
|
+
huffTab[i].val = highVal;
|
3215
|
+
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
|
3216
|
+
huffTab[i].rangeLen = 32;
|
3217
|
+
++i;
|
3218
|
+
if (oob) {
|
3219
|
+
huffTab[i].val = 0;
|
3220
|
+
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
|
3221
|
+
huffTab[i].rangeLen = jbig2HuffmanOOB;
|
3222
|
+
++i;
|
3223
|
+
}
|
3224
|
+
huffTab[i].val = 0;
|
3225
|
+
huffTab[i].prefixLen = 0;
|
3226
|
+
huffTab[i].rangeLen = jbig2HuffmanEOT;
|
3227
|
+
huffDecoder->buildTable(huffTab, i);
|
3228
|
+
|
3229
|
+
// create and store the new table segment
|
3230
|
+
segments->append(new JBIG2CodeTable(segNum, huffTab));
|
3231
|
+
|
3232
|
+
return;
|
3233
|
+
|
3234
|
+
eofError:
|
3235
|
+
error(getPos(), "Unexpected EOF in JBIG2 stream");
|
3236
|
+
}
|
3237
|
+
|
3238
|
+
void JBIG2Stream::readExtensionSeg(Guint length) {
|
3239
|
+
Guint i;
|
3240
|
+
|
3241
|
+
// skip the segment
|
3242
|
+
for (i = 0; i < length; ++i) {
|
3243
|
+
curStr->getChar();
|
3244
|
+
}
|
3245
|
+
}
|
3246
|
+
|
3247
|
+
JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
|
3248
|
+
JBIG2Segment *seg;
|
3249
|
+
int i;
|
3250
|
+
|
3251
|
+
for (i = 0; i < globalSegments->getLength(); ++i) {
|
3252
|
+
seg = (JBIG2Segment *)globalSegments->get(i);
|
3253
|
+
if (seg->getSegNum() == segNum) {
|
3254
|
+
return seg;
|
3255
|
+
}
|
3256
|
+
}
|
3257
|
+
for (i = 0; i < segments->getLength(); ++i) {
|
3258
|
+
seg = (JBIG2Segment *)segments->get(i);
|
3259
|
+
if (seg->getSegNum() == segNum) {
|
3260
|
+
return seg;
|
3261
|
+
}
|
3262
|
+
}
|
3263
|
+
return NULL;
|
3264
|
+
}
|
3265
|
+
|
3266
|
+
void JBIG2Stream::discardSegment(Guint segNum) {
|
3267
|
+
JBIG2Segment *seg;
|
3268
|
+
int i;
|
3269
|
+
|
3270
|
+
for (i = 0; i < globalSegments->getLength(); ++i) {
|
3271
|
+
seg = (JBIG2Segment *)globalSegments->get(i);
|
3272
|
+
if (seg->getSegNum() == segNum) {
|
3273
|
+
globalSegments->del(i);
|
3274
|
+
return;
|
3275
|
+
}
|
3276
|
+
}
|
3277
|
+
for (i = 0; i < segments->getLength(); ++i) {
|
3278
|
+
seg = (JBIG2Segment *)segments->get(i);
|
3279
|
+
if (seg->getSegNum() == segNum) {
|
3280
|
+
segments->del(i);
|
3281
|
+
return;
|
3282
|
+
}
|
3283
|
+
}
|
3284
|
+
}
|
3285
|
+
|
3286
|
+
void JBIG2Stream::resetGenericStats(Guint templ,
|
3287
|
+
JArithmeticDecoderStats *prevStats) {
|
3288
|
+
int size;
|
3289
|
+
|
3290
|
+
size = contextSize[templ];
|
3291
|
+
if (prevStats && prevStats->getContextSize() == size) {
|
3292
|
+
if (genericRegionStats->getContextSize() == size) {
|
3293
|
+
genericRegionStats->copyFrom(prevStats);
|
3294
|
+
} else {
|
3295
|
+
delete genericRegionStats;
|
3296
|
+
genericRegionStats = prevStats->copy();
|
3297
|
+
}
|
3298
|
+
} else {
|
3299
|
+
if (genericRegionStats->getContextSize() == size) {
|
3300
|
+
genericRegionStats->reset();
|
3301
|
+
} else {
|
3302
|
+
delete genericRegionStats;
|
3303
|
+
genericRegionStats = new JArithmeticDecoderStats(1 << size);
|
3304
|
+
}
|
3305
|
+
}
|
3306
|
+
}
|
3307
|
+
|
3308
|
+
void JBIG2Stream::resetRefinementStats(Guint templ,
|
3309
|
+
JArithmeticDecoderStats *prevStats) {
|
3310
|
+
int size;
|
3311
|
+
|
3312
|
+
size = refContextSize[templ];
|
3313
|
+
if (prevStats && prevStats->getContextSize() == size) {
|
3314
|
+
if (refinementRegionStats->getContextSize() == size) {
|
3315
|
+
refinementRegionStats->copyFrom(prevStats);
|
3316
|
+
} else {
|
3317
|
+
delete refinementRegionStats;
|
3318
|
+
refinementRegionStats = prevStats->copy();
|
3319
|
+
}
|
3320
|
+
} else {
|
3321
|
+
if (refinementRegionStats->getContextSize() == size) {
|
3322
|
+
refinementRegionStats->reset();
|
3323
|
+
} else {
|
3324
|
+
delete refinementRegionStats;
|
3325
|
+
refinementRegionStats = new JArithmeticDecoderStats(1 << size);
|
3326
|
+
}
|
3327
|
+
}
|
3328
|
+
}
|
3329
|
+
|
3330
|
+
void JBIG2Stream::resetIntStats(int symCodeLen) {
|
3331
|
+
iadhStats->reset();
|
3332
|
+
iadwStats->reset();
|
3333
|
+
iaexStats->reset();
|
3334
|
+
iaaiStats->reset();
|
3335
|
+
iadtStats->reset();
|
3336
|
+
iaitStats->reset();
|
3337
|
+
iafsStats->reset();
|
3338
|
+
iadsStats->reset();
|
3339
|
+
iardxStats->reset();
|
3340
|
+
iardyStats->reset();
|
3341
|
+
iardwStats->reset();
|
3342
|
+
iardhStats->reset();
|
3343
|
+
iariStats->reset();
|
3344
|
+
if (iaidStats->getContextSize() == 1 << (symCodeLen + 1)) {
|
3345
|
+
iaidStats->reset();
|
3346
|
+
} else {
|
3347
|
+
delete iaidStats;
|
3348
|
+
iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
|
3349
|
+
}
|
3350
|
+
}
|
3351
|
+
|
3352
|
+
GBool JBIG2Stream::readUByte(Guint *x) {
|
3353
|
+
int c0;
|
3354
|
+
|
3355
|
+
if ((c0 = curStr->getChar()) == EOF) {
|
3356
|
+
return gFalse;
|
3357
|
+
}
|
3358
|
+
*x = (Guint)c0;
|
3359
|
+
return gTrue;
|
3360
|
+
}
|
3361
|
+
|
3362
|
+
GBool JBIG2Stream::readByte(int *x) {
|
3363
|
+
int c0;
|
3364
|
+
|
3365
|
+
if ((c0 = curStr->getChar()) == EOF) {
|
3366
|
+
return gFalse;
|
3367
|
+
}
|
3368
|
+
*x = c0;
|
3369
|
+
if (c0 & 0x80) {
|
3370
|
+
*x |= -1 - 0xff;
|
3371
|
+
}
|
3372
|
+
return gTrue;
|
3373
|
+
}
|
3374
|
+
|
3375
|
+
GBool JBIG2Stream::readUWord(Guint *x) {
|
3376
|
+
int c0, c1;
|
3377
|
+
|
3378
|
+
if ((c0 = curStr->getChar()) == EOF ||
|
3379
|
+
(c1 = curStr->getChar()) == EOF) {
|
3380
|
+
return gFalse;
|
3381
|
+
}
|
3382
|
+
*x = (Guint)((c0 << 8) | c1);
|
3383
|
+
return gTrue;
|
3384
|
+
}
|
3385
|
+
|
3386
|
+
GBool JBIG2Stream::readULong(Guint *x) {
|
3387
|
+
int c0, c1, c2, c3;
|
3388
|
+
|
3389
|
+
if ((c0 = curStr->getChar()) == EOF ||
|
3390
|
+
(c1 = curStr->getChar()) == EOF ||
|
3391
|
+
(c2 = curStr->getChar()) == EOF ||
|
3392
|
+
(c3 = curStr->getChar()) == EOF) {
|
3393
|
+
return gFalse;
|
3394
|
+
}
|
3395
|
+
*x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
|
3396
|
+
return gTrue;
|
3397
|
+
}
|
3398
|
+
|
3399
|
+
GBool JBIG2Stream::readLong(int *x) {
|
3400
|
+
int c0, c1, c2, c3;
|
3401
|
+
|
3402
|
+
if ((c0 = curStr->getChar()) == EOF ||
|
3403
|
+
(c1 = curStr->getChar()) == EOF ||
|
3404
|
+
(c2 = curStr->getChar()) == EOF ||
|
3405
|
+
(c3 = curStr->getChar()) == EOF) {
|
3406
|
+
return gFalse;
|
3407
|
+
}
|
3408
|
+
*x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
|
3409
|
+
if (c0 & 0x80) {
|
3410
|
+
*x |= -1 - (int)0xffffffff;
|
3411
|
+
}
|
3412
|
+
return gTrue;
|
3413
|
+
}
|