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.
Files changed (473) hide show
  1. data/README.markdown +9 -0
  2. data/bin/.gitkeep +0 -0
  3. data/ext/extconf.rb +30 -0
  4. data/lib/pdf2json.rb +8 -0
  5. data/pdf2json-0.52-source/AUTHORS +24 -0
  6. data/pdf2json-0.52-source/CHANGES +11 -0
  7. data/pdf2json-0.52-source/Makefile +84 -0
  8. data/pdf2json-0.52-source/Makefile.in +84 -0
  9. data/pdf2json-0.52-source/aclocal.m4 +274 -0
  10. data/pdf2json-0.52-source/aconf-win32.h +86 -0
  11. data/pdf2json-0.52-source/aconf.h +42 -0
  12. data/pdf2json-0.52-source/aconf.h.in +41 -0
  13. data/pdf2json-0.52-source/autom4te.cache/output.0 +6908 -0
  14. data/pdf2json-0.52-source/autom4te.cache/requests +76 -0
  15. data/pdf2json-0.52-source/autom4te.cache/traces.0 +466 -0
  16. data/pdf2json-0.52-source/config.log +1259 -0
  17. data/pdf2json-0.52-source/config.status +1050 -0
  18. data/pdf2json-0.52-source/configure +6908 -0
  19. data/pdf2json-0.52-source/configure.ac +93 -0
  20. data/pdf2json-0.52-source/doc/pdffonts.1 +130 -0
  21. data/pdf2json-0.52-source/doc/pdffonts.cat +107 -0
  22. data/pdf2json-0.52-source/doc/pdffonts.hlp +117 -0
  23. data/pdf2json-0.52-source/doc/pdfimages.1 +102 -0
  24. data/pdf2json-0.52-source/doc/pdfimages.cat +92 -0
  25. data/pdf2json-0.52-source/doc/pdfimages.hlp +101 -0
  26. data/pdf2json-0.52-source/doc/pdfinfo.1 +158 -0
  27. data/pdf2json-0.52-source/doc/pdfinfo.cat +119 -0
  28. data/pdf2json-0.52-source/doc/pdfinfo.hlp +129 -0
  29. data/pdf2json-0.52-source/doc/pdftoppm.1 +115 -0
  30. data/pdf2json-0.52-source/doc/pdftoppm.cat +105 -0
  31. data/pdf2json-0.52-source/doc/pdftoppm.hlp +114 -0
  32. data/pdf2json-0.52-source/doc/pdftops.1 +229 -0
  33. data/pdf2json-0.52-source/doc/pdftops.cat +221 -0
  34. data/pdf2json-0.52-source/doc/pdftops.hlp +231 -0
  35. data/pdf2json-0.52-source/doc/pdftotext.1 +137 -0
  36. data/pdf2json-0.52-source/doc/pdftotext.cat +120 -0
  37. data/pdf2json-0.52-source/doc/pdftotext.hlp +133 -0
  38. data/pdf2json-0.52-source/doc/sample-xpdfrc +91 -0
  39. data/pdf2json-0.52-source/doc/xpdf.1 +513 -0
  40. data/pdf2json-0.52-source/doc/xpdf.cat +476 -0
  41. data/pdf2json-0.52-source/doc/xpdf.hlp +489 -0
  42. data/pdf2json-0.52-source/doc/xpdfrc.5 +480 -0
  43. data/pdf2json-0.52-source/doc/xpdfrc.cat +474 -0
  44. data/pdf2json-0.52-source/doc/xpdfrc.hlp +479 -0
  45. data/pdf2json-0.52-source/fofi/.DS_Store +0 -0
  46. data/pdf2json-0.52-source/fofi/FoFiBase.cc +156 -0
  47. data/pdf2json-0.52-source/fofi/FoFiBase.h +57 -0
  48. data/pdf2json-0.52-source/fofi/FoFiBase.o +0 -0
  49. data/pdf2json-0.52-source/fofi/FoFiEncodings.cc +994 -0
  50. data/pdf2json-0.52-source/fofi/FoFiEncodings.h +36 -0
  51. data/pdf2json-0.52-source/fofi/FoFiEncodings.o +0 -0
  52. data/pdf2json-0.52-source/fofi/FoFiTrueType.cc +2027 -0
  53. data/pdf2json-0.52-source/fofi/FoFiTrueType.h +174 -0
  54. data/pdf2json-0.52-source/fofi/FoFiTrueType.o +0 -0
  55. data/pdf2json-0.52-source/fofi/FoFiType1.cc +252 -0
  56. data/pdf2json-0.52-source/fofi/FoFiType1.h +59 -0
  57. data/pdf2json-0.52-source/fofi/FoFiType1.o +0 -0
  58. data/pdf2json-0.52-source/fofi/FoFiType1C.cc +2603 -0
  59. data/pdf2json-0.52-source/fofi/FoFiType1C.h +233 -0
  60. data/pdf2json-0.52-source/fofi/FoFiType1C.o +0 -0
  61. data/pdf2json-0.52-source/fofi/Makefile +70 -0
  62. data/pdf2json-0.52-source/fofi/Makefile.dep +0 -0
  63. data/pdf2json-0.52-source/fofi/Makefile.in +70 -0
  64. data/pdf2json-0.52-source/fofi/libfofi.a +0 -0
  65. data/pdf2json-0.52-source/fofi/vms_make.com +0 -0
  66. data/pdf2json-0.52-source/freetype.win32/.DS_Store +0 -0
  67. data/pdf2json-0.52-source/freetype.win32/include/.DS_Store +0 -0
  68. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftconfig.h +528 -0
  69. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftheader.h +780 -0
  70. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftmodule.h +32 -0
  71. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftoption.h +733 -0
  72. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftstdlib.h +173 -0
  73. data/pdf2json-0.52-source/freetype.win32/include/freetype/freetype.h +3919 -0
  74. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftadvanc.h +179 -0
  75. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbbox.h +94 -0
  76. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbdf.h +209 -0
  77. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbitmap.h +227 -0
  78. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcache.h +1128 -0
  79. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftchapters.h +103 -0
  80. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcid.h +166 -0
  81. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrdef.h +244 -0
  82. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrors.h +206 -0
  83. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgasp.h +120 -0
  84. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftglyph.h +613 -0
  85. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgxval.h +358 -0
  86. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgzip.h +102 -0
  87. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftimage.h +1313 -0
  88. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftincrem.h +353 -0
  89. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlcdfil.h +213 -0
  90. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlist.h +277 -0
  91. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlzw.h +99 -0
  92. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmac.h +274 -0
  93. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmm.h +378 -0
  94. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmodapi.h +483 -0
  95. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmoderr.h +155 -0
  96. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftotval.h +203 -0
  97. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftoutln.h +537 -0
  98. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftpfr.h +172 -0
  99. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftrender.h +230 -0
  100. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsizes.h +159 -0
  101. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsnames.h +200 -0
  102. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftstroke.h +716 -0
  103. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsynth.h +80 -0
  104. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsystem.h +347 -0
  105. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttrigon.h +350 -0
  106. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttypes.h +588 -0
  107. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftwinfnt.h +274 -0
  108. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftxf86.h +83 -0
  109. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/autohint.h +231 -0
  110. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftcalc.h +179 -0
  111. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdebug.h +250 -0
  112. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdriver.h +422 -0
  113. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftgloadr.h +168 -0
  114. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftmemory.h +380 -0
  115. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftobjs.h +1428 -0
  116. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftpic.h +67 -0
  117. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftrfork.h +196 -0
  118. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftserv.h +620 -0
  119. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftstream.h +539 -0
  120. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/fttrace.h +139 -0
  121. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftvalid.h +150 -0
  122. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/internal.h +51 -0
  123. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pcftypes.h +56 -0
  124. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/psaux.h +873 -0
  125. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pshints.h +712 -0
  126. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svbdf.h +77 -0
  127. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svcid.h +83 -0
  128. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgldict.h +82 -0
  129. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgxval.h +72 -0
  130. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svkern.h +51 -0
  131. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svmm.h +104 -0
  132. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svotval.h +55 -0
  133. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpfr.h +66 -0
  134. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpostnm.h +79 -0
  135. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpscmap.h +164 -0
  136. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpsinfo.h +92 -0
  137. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svsfnt.h +102 -0
  138. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttcmap.h +106 -0
  139. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svtteng.h +53 -0
  140. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttglyf.h +67 -0
  141. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svwinfnt.h +50 -0
  142. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svxf86nm.h +55 -0
  143. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/sfnt.h +897 -0
  144. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/t1types.h +270 -0
  145. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/tttypes.h +1543 -0
  146. data/pdf2json-0.52-source/freetype.win32/include/freetype/t1tables.h +504 -0
  147. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttnameid.h +1247 -0
  148. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttables.h +759 -0
  149. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttags.h +107 -0
  150. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttunpat.h +59 -0
  151. data/pdf2json-0.52-source/freetype.win32/include/ft2build.h +39 -0
  152. data/pdf2json-0.52-source/freetype.win32/lib/freetype_a.lib +0 -0
  153. data/pdf2json-0.52-source/goo/.DS_Store +0 -0
  154. data/pdf2json-0.52-source/goo/FixedPoint.cc +118 -0
  155. data/pdf2json-0.52-source/goo/FixedPoint.h +155 -0
  156. data/pdf2json-0.52-source/goo/FixedPoint.o +0 -0
  157. data/pdf2json-0.52-source/goo/GHash.cc +380 -0
  158. data/pdf2json-0.52-source/goo/GHash.h +78 -0
  159. data/pdf2json-0.52-source/goo/GHash.o +0 -0
  160. data/pdf2json-0.52-source/goo/GList.cc +97 -0
  161. data/pdf2json-0.52-source/goo/GList.h +96 -0
  162. data/pdf2json-0.52-source/goo/GList.o +0 -0
  163. data/pdf2json-0.52-source/goo/GMutex.h +49 -0
  164. data/pdf2json-0.52-source/goo/GString.cc +724 -0
  165. data/pdf2json-0.52-source/goo/GString.cc.fixed +718 -0
  166. data/pdf2json-0.52-source/goo/GString.h +136 -0
  167. data/pdf2json-0.52-source/goo/GString.o +0 -0
  168. data/pdf2json-0.52-source/goo/ImgWriter.o +0 -0
  169. data/pdf2json-0.52-source/goo/JpegWriter.o +0 -0
  170. data/pdf2json-0.52-source/goo/Makefile +72 -0
  171. data/pdf2json-0.52-source/goo/Makefile.dep +0 -0
  172. data/pdf2json-0.52-source/goo/Makefile.in +72 -0
  173. data/pdf2json-0.52-source/goo/PNGWriter.o +0 -0
  174. data/pdf2json-0.52-source/goo/gfile.cc +731 -0
  175. data/pdf2json-0.52-source/goo/gfile.h +138 -0
  176. data/pdf2json-0.52-source/goo/gfile.o +0 -0
  177. data/pdf2json-0.52-source/goo/gmem.cc +264 -0
  178. data/pdf2json-0.52-source/goo/gmem.h +79 -0
  179. data/pdf2json-0.52-source/goo/gmem.o +0 -0
  180. data/pdf2json-0.52-source/goo/gmempp.cc +32 -0
  181. data/pdf2json-0.52-source/goo/gmempp.o +0 -0
  182. data/pdf2json-0.52-source/goo/gtypes.h +29 -0
  183. data/pdf2json-0.52-source/goo/libGoo.a +0 -0
  184. data/pdf2json-0.52-source/goo/parseargs.c +190 -0
  185. data/pdf2json-0.52-source/goo/parseargs.h +71 -0
  186. data/pdf2json-0.52-source/goo/parseargs.o +0 -0
  187. data/pdf2json-0.52-source/goo/vms_directory.c +214 -0
  188. data/pdf2json-0.52-source/goo/vms_dirent.h +67 -0
  189. data/pdf2json-0.52-source/goo/vms_make.com +82 -0
  190. data/pdf2json-0.52-source/goo/vms_sys_dirent.h +54 -0
  191. data/pdf2json-0.52-source/goo/vms_unix_time.h +102 -0
  192. data/pdf2json-0.52-source/goo/vms_unix_times.c +42 -0
  193. data/pdf2json-0.52-source/goo/vms_unlink.c +22 -0
  194. data/pdf2json-0.52-source/ms_make.bat +199 -0
  195. data/pdf2json-0.52-source/splash/.DS_Store +0 -0
  196. data/pdf2json-0.52-source/splash/Makefile +103 -0
  197. data/pdf2json-0.52-source/splash/Makefile.dep +0 -0
  198. data/pdf2json-0.52-source/splash/Makefile.in +103 -0
  199. data/pdf2json-0.52-source/splash/Splash.cc +3310 -0
  200. data/pdf2json-0.52-source/splash/Splash.h +293 -0
  201. data/pdf2json-0.52-source/splash/Splash.o +0 -0
  202. data/pdf2json-0.52-source/splash/SplashBitmap.cc +188 -0
  203. data/pdf2json-0.52-source/splash/SplashBitmap.h +64 -0
  204. data/pdf2json-0.52-source/splash/SplashBitmap.o +0 -0
  205. data/pdf2json-0.52-source/splash/SplashClip.cc +382 -0
  206. data/pdf2json-0.52-source/splash/SplashClip.h +107 -0
  207. data/pdf2json-0.52-source/splash/SplashClip.o +0 -0
  208. data/pdf2json-0.52-source/splash/SplashErrorCodes.h +32 -0
  209. data/pdf2json-0.52-source/splash/SplashFTFont.cc +357 -0
  210. data/pdf2json-0.52-source/splash/SplashFTFont.h +58 -0
  211. data/pdf2json-0.52-source/splash/SplashFTFont.o +0 -0
  212. data/pdf2json-0.52-source/splash/SplashFTFontEngine.cc +179 -0
  213. data/pdf2json-0.52-source/splash/SplashFTFontEngine.h +65 -0
  214. data/pdf2json-0.52-source/splash/SplashFTFontEngine.o +0 -0
  215. data/pdf2json-0.52-source/splash/SplashFTFontFile.cc +114 -0
  216. data/pdf2json-0.52-source/splash/SplashFTFontFile.h +73 -0
  217. data/pdf2json-0.52-source/splash/SplashFTFontFile.o +0 -0
  218. data/pdf2json-0.52-source/splash/SplashFont.cc +176 -0
  219. data/pdf2json-0.52-source/splash/SplashFont.h +104 -0
  220. data/pdf2json-0.52-source/splash/SplashFont.o +0 -0
  221. data/pdf2json-0.52-source/splash/SplashFontEngine.cc +317 -0
  222. data/pdf2json-0.52-source/splash/SplashFontEngine.h +91 -0
  223. data/pdf2json-0.52-source/splash/SplashFontEngine.o +0 -0
  224. data/pdf2json-0.52-source/splash/SplashFontFile.cc +55 -0
  225. data/pdf2json-0.52-source/splash/SplashFontFile.h +60 -0
  226. data/pdf2json-0.52-source/splash/SplashFontFile.o +0 -0
  227. data/pdf2json-0.52-source/splash/SplashFontFileID.cc +23 -0
  228. data/pdf2json-0.52-source/splash/SplashFontFileID.h +30 -0
  229. data/pdf2json-0.52-source/splash/SplashFontFileID.o +0 -0
  230. data/pdf2json-0.52-source/splash/SplashGlyphBitmap.h +26 -0
  231. data/pdf2json-0.52-source/splash/SplashMath.h +89 -0
  232. data/pdf2json-0.52-source/splash/SplashPath.cc +184 -0
  233. data/pdf2json-0.52-source/splash/SplashPath.h +121 -0
  234. data/pdf2json-0.52-source/splash/SplashPath.o +0 -0
  235. data/pdf2json-0.52-source/splash/SplashPattern.cc +40 -0
  236. data/pdf2json-0.52-source/splash/SplashPattern.h +65 -0
  237. data/pdf2json-0.52-source/splash/SplashPattern.o +0 -0
  238. data/pdf2json-0.52-source/splash/SplashScreen.cc +383 -0
  239. data/pdf2json-0.52-source/splash/SplashScreen.h +56 -0
  240. data/pdf2json-0.52-source/splash/SplashScreen.o +0 -0
  241. data/pdf2json-0.52-source/splash/SplashState.cc +165 -0
  242. data/pdf2json-0.52-source/splash/SplashState.h +103 -0
  243. data/pdf2json-0.52-source/splash/SplashState.o +0 -0
  244. data/pdf2json-0.52-source/splash/SplashT1Font.cc +287 -0
  245. data/pdf2json-0.52-source/splash/SplashT1Font.h +57 -0
  246. data/pdf2json-0.52-source/splash/SplashT1Font.o +0 -0
  247. data/pdf2json-0.52-source/splash/SplashT1FontEngine.cc +124 -0
  248. data/pdf2json-0.52-source/splash/SplashT1FontEngine.h +53 -0
  249. data/pdf2json-0.52-source/splash/SplashT1FontEngine.o +0 -0
  250. data/pdf2json-0.52-source/splash/SplashT1FontFile.cc +97 -0
  251. data/pdf2json-0.52-source/splash/SplashT1FontFile.h +58 -0
  252. data/pdf2json-0.52-source/splash/SplashT1FontFile.o +0 -0
  253. data/pdf2json-0.52-source/splash/SplashTypes.h +132 -0
  254. data/pdf2json-0.52-source/splash/SplashXPath.cc +438 -0
  255. data/pdf2json-0.52-source/splash/SplashXPath.h +100 -0
  256. data/pdf2json-0.52-source/splash/SplashXPath.o +0 -0
  257. data/pdf2json-0.52-source/splash/SplashXPathScanner.cc +428 -0
  258. data/pdf2json-0.52-source/splash/SplashXPathScanner.h +87 -0
  259. data/pdf2json-0.52-source/splash/SplashXPathScanner.o +0 -0
  260. data/pdf2json-0.52-source/splash/libsplash.a +0 -0
  261. data/pdf2json-0.52-source/splash/vms_make.com +0 -0
  262. data/pdf2json-0.52-source/src/.DS_Store +0 -0
  263. data/pdf2json-0.52-source/src/GVector.h +101 -0
  264. data/pdf2json-0.52-source/src/ImgOutputDev.cc +1243 -0
  265. data/pdf2json-0.52-source/src/ImgOutputDev.h +307 -0
  266. data/pdf2json-0.52-source/src/ImgOutputDev.o +0 -0
  267. data/pdf2json-0.52-source/src/Makefile +68 -0
  268. data/pdf2json-0.52-source/src/Makefile.in +68 -0
  269. data/pdf2json-0.52-source/src/XmlFonts.cc +367 -0
  270. data/pdf2json-0.52-source/src/XmlFonts.h +91 -0
  271. data/pdf2json-0.52-source/src/XmlFonts.o +0 -0
  272. data/pdf2json-0.52-source/src/XmlLinks.cc +101 -0
  273. data/pdf2json-0.52-source/src/XmlLinks.h +54 -0
  274. data/pdf2json-0.52-source/src/XmlLinks.o +0 -0
  275. data/pdf2json-0.52-source/src/pdf2json +0 -0
  276. data/pdf2json-0.52-source/src/pdf2json.cc +343 -0
  277. data/pdf2json-0.52-source/src/pdf2json.o +0 -0
  278. data/pdf2json-0.52-source/src/pdf2xml.dtd +22 -0
  279. data/pdf2json-0.52-source/src/pdf2xmljson.dtd +9 -0
  280. data/pdf2json-0.52-source/xpdf/.DS_Store +0 -0
  281. data/pdf2json-0.52-source/xpdf/Annot.cc +1556 -0
  282. data/pdf2json-0.52-source/xpdf/Annot.h +142 -0
  283. data/pdf2json-0.52-source/xpdf/Annot.o +0 -0
  284. data/pdf2json-0.52-source/xpdf/Array.cc +73 -0
  285. data/pdf2json-0.52-source/xpdf/Array.h +58 -0
  286. data/pdf2json-0.52-source/xpdf/Array.o +0 -0
  287. data/pdf2json-0.52-source/xpdf/BuiltinFont.cc +65 -0
  288. data/pdf2json-0.52-source/xpdf/BuiltinFont.h +57 -0
  289. data/pdf2json-0.52-source/xpdf/BuiltinFont.o +0 -0
  290. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.cc +4284 -0
  291. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.h +23 -0
  292. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.o +0 -0
  293. data/pdf2json-0.52-source/xpdf/CMap.cc +408 -0
  294. data/pdf2json-0.52-source/xpdf/CMap.h +102 -0
  295. data/pdf2json-0.52-source/xpdf/CMap.o +0 -0
  296. data/pdf2json-0.52-source/xpdf/Catalog.cc +374 -0
  297. data/pdf2json-0.52-source/xpdf/Catalog.h +97 -0
  298. data/pdf2json-0.52-source/xpdf/Catalog.o +0 -0
  299. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.cc +540 -0
  300. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.h +117 -0
  301. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.o +0 -0
  302. data/pdf2json-0.52-source/xpdf/CharTypes.h +24 -0
  303. data/pdf2json-0.52-source/xpdf/CompactFontTables.h +464 -0
  304. data/pdf2json-0.52-source/xpdf/CoreOutputDev.cc +61 -0
  305. data/pdf2json-0.52-source/xpdf/CoreOutputDev.h +61 -0
  306. data/pdf2json-0.52-source/xpdf/Decrypt.cc +776 -0
  307. data/pdf2json-0.52-source/xpdf/Decrypt.h +95 -0
  308. data/pdf2json-0.52-source/xpdf/Decrypt.o +0 -0
  309. data/pdf2json-0.52-source/xpdf/Dict.cc +95 -0
  310. data/pdf2json-0.52-source/xpdf/Dict.h +77 -0
  311. data/pdf2json-0.52-source/xpdf/Dict.o +0 -0
  312. data/pdf2json-0.52-source/xpdf/Error.cc +38 -0
  313. data/pdf2json-0.52-source/xpdf/Error.h +23 -0
  314. data/pdf2json-0.52-source/xpdf/Error.o +0 -0
  315. data/pdf2json-0.52-source/xpdf/ErrorCodes.h +36 -0
  316. data/pdf2json-0.52-source/xpdf/FontEncodingTables.cc +1824 -0
  317. data/pdf2json-0.52-source/xpdf/FontEncodingTables.h +20 -0
  318. data/pdf2json-0.52-source/xpdf/FontEncodingTables.o +0 -0
  319. data/pdf2json-0.52-source/xpdf/Function.cc +1573 -0
  320. data/pdf2json-0.52-source/xpdf/Function.h +229 -0
  321. data/pdf2json-0.52-source/xpdf/Function.o +0 -0
  322. data/pdf2json-0.52-source/xpdf/Gfx.cc +4187 -0
  323. data/pdf2json-0.52-source/xpdf/Gfx.h +312 -0
  324. data/pdf2json-0.52-source/xpdf/Gfx.o +0 -0
  325. data/pdf2json-0.52-source/xpdf/GfxFont.cc +1568 -0
  326. data/pdf2json-0.52-source/xpdf/GfxFont.h +320 -0
  327. data/pdf2json-0.52-source/xpdf/GfxFont.o +0 -0
  328. data/pdf2json-0.52-source/xpdf/GfxState.cc +4137 -0
  329. data/pdf2json-0.52-source/xpdf/GfxState.h +1244 -0
  330. data/pdf2json-0.52-source/xpdf/GfxState.o +0 -0
  331. data/pdf2json-0.52-source/xpdf/GlobalParams.cc +2924 -0
  332. data/pdf2json-0.52-source/xpdf/GlobalParams.cc.old +2908 -0
  333. data/pdf2json-0.52-source/xpdf/GlobalParams.h +466 -0
  334. data/pdf2json-0.52-source/xpdf/GlobalParams.h.old +463 -0
  335. data/pdf2json-0.52-source/xpdf/GlobalParams.o +0 -0
  336. data/pdf2json-0.52-source/xpdf/ImageOutputDev.cc +195 -0
  337. data/pdf2json-0.52-source/xpdf/ImageOutputDev.h +76 -0
  338. data/pdf2json-0.52-source/xpdf/ImageOutputDev.o +0 -0
  339. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.cc +322 -0
  340. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.h +109 -0
  341. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.o +0 -0
  342. data/pdf2json-0.52-source/xpdf/JBIG2Stream.cc +3413 -0
  343. data/pdf2json-0.52-source/xpdf/JBIG2Stream.h +145 -0
  344. data/pdf2json-0.52-source/xpdf/JBIG2Stream.o +0 -0
  345. data/pdf2json-0.52-source/xpdf/JPXStream.cc +3144 -0
  346. data/pdf2json-0.52-source/xpdf/JPXStream.h +351 -0
  347. data/pdf2json-0.52-source/xpdf/JPXStream.o +0 -0
  348. data/pdf2json-0.52-source/xpdf/Lexer.cc +485 -0
  349. data/pdf2json-0.52-source/xpdf/Lexer.h +80 -0
  350. data/pdf2json-0.52-source/xpdf/Lexer.o +0 -0
  351. data/pdf2json-0.52-source/xpdf/Link.cc +806 -0
  352. data/pdf2json-0.52-source/xpdf/Link.cc.old +784 -0
  353. data/pdf2json-0.52-source/xpdf/Link.h +415 -0
  354. data/pdf2json-0.52-source/xpdf/Link.h.old +369 -0
  355. data/pdf2json-0.52-source/xpdf/Link.o +0 -0
  356. data/pdf2json-0.52-source/xpdf/Makefile +232 -0
  357. data/pdf2json-0.52-source/xpdf/Makefile.dep +0 -0
  358. data/pdf2json-0.52-source/xpdf/Makefile.in +232 -0
  359. data/pdf2json-0.52-source/xpdf/NameToCharCode.cc +116 -0
  360. data/pdf2json-0.52-source/xpdf/NameToCharCode.h +42 -0
  361. data/pdf2json-0.52-source/xpdf/NameToCharCode.o +0 -0
  362. data/pdf2json-0.52-source/xpdf/NameToUnicodeTable.h +1097 -0
  363. data/pdf2json-0.52-source/xpdf/Object.cc +231 -0
  364. data/pdf2json-0.52-source/xpdf/Object.h +303 -0
  365. data/pdf2json-0.52-source/xpdf/Object.o +0 -0
  366. data/pdf2json-0.52-source/xpdf/Outline.cc +151 -0
  367. data/pdf2json-0.52-source/xpdf/Outline.h +76 -0
  368. data/pdf2json-0.52-source/xpdf/Outline.o +0 -0
  369. data/pdf2json-0.52-source/xpdf/OutputDev.cc +131 -0
  370. data/pdf2json-0.52-source/xpdf/OutputDev.h +253 -0
  371. data/pdf2json-0.52-source/xpdf/OutputDev.o +0 -0
  372. data/pdf2json-0.52-source/xpdf/PDFCore.cc +2044 -0
  373. data/pdf2json-0.52-source/xpdf/PDFCore.h +321 -0
  374. data/pdf2json-0.52-source/xpdf/PDFDoc.cc +404 -0
  375. data/pdf2json-0.52-source/xpdf/PDFDoc.h +183 -0
  376. data/pdf2json-0.52-source/xpdf/PDFDoc.o +0 -0
  377. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.cc +44 -0
  378. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.h +16 -0
  379. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.o +0 -0
  380. data/pdf2json-0.52-source/xpdf/PSOutputDev.cc +6224 -0
  381. data/pdf2json-0.52-source/xpdf/PSOutputDev.h +395 -0
  382. data/pdf2json-0.52-source/xpdf/PSOutputDev.o +0 -0
  383. data/pdf2json-0.52-source/xpdf/PSTokenizer.cc +135 -0
  384. data/pdf2json-0.52-source/xpdf/PSTokenizer.h +41 -0
  385. data/pdf2json-0.52-source/xpdf/PSTokenizer.o +0 -0
  386. data/pdf2json-0.52-source/xpdf/Page.cc +454 -0
  387. data/pdf2json-0.52-source/xpdf/Page.h +187 -0
  388. data/pdf2json-0.52-source/xpdf/Page.o +0 -0
  389. data/pdf2json-0.52-source/xpdf/Parser.cc +227 -0
  390. data/pdf2json-0.52-source/xpdf/Parser.h +59 -0
  391. data/pdf2json-0.52-source/xpdf/Parser.o +0 -0
  392. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.cc +257 -0
  393. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.h +130 -0
  394. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.o +0 -0
  395. data/pdf2json-0.52-source/xpdf/SecurityHandler.cc +390 -0
  396. data/pdf2json-0.52-source/xpdf/SecurityHandler.h +160 -0
  397. data/pdf2json-0.52-source/xpdf/SecurityHandler.o +0 -0
  398. data/pdf2json-0.52-source/xpdf/SplashOutputDev.cc +2845 -0
  399. data/pdf2json-0.52-source/xpdf/SplashOutputDev.h +247 -0
  400. data/pdf2json-0.52-source/xpdf/SplashOutputDev.o +0 -0
  401. data/pdf2json-0.52-source/xpdf/Stream-CCITT.h +459 -0
  402. data/pdf2json-0.52-source/xpdf/Stream.cc +4627 -0
  403. data/pdf2json-0.52-source/xpdf/Stream.h +858 -0
  404. data/pdf2json-0.52-source/xpdf/Stream.o +0 -0
  405. data/pdf2json-0.52-source/xpdf/TextOutputDev.cc +4090 -0
  406. data/pdf2json-0.52-source/xpdf/TextOutputDev.h +661 -0
  407. data/pdf2json-0.52-source/xpdf/TextOutputDev.o +0 -0
  408. data/pdf2json-0.52-source/xpdf/UTF8.h +56 -0
  409. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc +302 -0
  410. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc.old +293 -0
  411. data/pdf2json-0.52-source/xpdf/UnicodeMap.h +135 -0
  412. data/pdf2json-0.52-source/xpdf/UnicodeMap.h.old +123 -0
  413. data/pdf2json-0.52-source/xpdf/UnicodeMap.o +0 -0
  414. data/pdf2json-0.52-source/xpdf/UnicodeMapTables.h +361 -0
  415. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.cc +949 -0
  416. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.h +20 -0
  417. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.o +0 -0
  418. data/pdf2json-0.52-source/xpdf/XPDFApp.cc +447 -0
  419. data/pdf2json-0.52-source/xpdf/XPDFApp.h +114 -0
  420. data/pdf2json-0.52-source/xpdf/XPDFCore.cc +1655 -0
  421. data/pdf2json-0.52-source/xpdf/XPDFCore.h +251 -0
  422. data/pdf2json-0.52-source/xpdf/XPDFTree.cc +931 -0
  423. data/pdf2json-0.52-source/xpdf/XPDFTree.h +45 -0
  424. data/pdf2json-0.52-source/xpdf/XPDFTreeP.h +87 -0
  425. data/pdf2json-0.52-source/xpdf/XPDFViewer.cc +3488 -0
  426. data/pdf2json-0.52-source/xpdf/XPDFViewer.h +352 -0
  427. data/pdf2json-0.52-source/xpdf/XRef.cc +896 -0
  428. data/pdf2json-0.52-source/xpdf/XRef.h +133 -0
  429. data/pdf2json-0.52-source/xpdf/XRef.o +0 -0
  430. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.cc +262 -0
  431. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.h +341 -0
  432. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.o +0 -0
  433. data/pdf2json-0.52-source/xpdf/about-text.h +48 -0
  434. data/pdf2json-0.52-source/xpdf/about.xbm +6 -0
  435. data/pdf2json-0.52-source/xpdf/backArrow.xbm +6 -0
  436. data/pdf2json-0.52-source/xpdf/backArrowDis.xbm +6 -0
  437. data/pdf2json-0.52-source/xpdf/config.h +112 -0
  438. data/pdf2json-0.52-source/xpdf/dblLeftArrow.xbm +6 -0
  439. data/pdf2json-0.52-source/xpdf/dblLeftArrowDis.xbm +6 -0
  440. data/pdf2json-0.52-source/xpdf/dblRightArrow.xbm +6 -0
  441. data/pdf2json-0.52-source/xpdf/dblRightArrowDis.xbm +6 -0
  442. data/pdf2json-0.52-source/xpdf/find.xbm +6 -0
  443. data/pdf2json-0.52-source/xpdf/findDis.xbm +6 -0
  444. data/pdf2json-0.52-source/xpdf/forwardArrow.xbm +6 -0
  445. data/pdf2json-0.52-source/xpdf/forwardArrowDis.xbm +6 -0
  446. data/pdf2json-0.52-source/xpdf/leftArrow.xbm +5 -0
  447. data/pdf2json-0.52-source/xpdf/leftArrowDis.xbm +5 -0
  448. data/pdf2json-0.52-source/xpdf/libXpdf.a +0 -0
  449. data/pdf2json-0.52-source/xpdf/pdffonts +0 -0
  450. data/pdf2json-0.52-source/xpdf/pdffonts.cc +298 -0
  451. data/pdf2json-0.52-source/xpdf/pdffonts.o +0 -0
  452. data/pdf2json-0.52-source/xpdf/pdfimages +0 -0
  453. data/pdf2json-0.52-source/xpdf/pdfimages.cc +155 -0
  454. data/pdf2json-0.52-source/xpdf/pdfimages.o +0 -0
  455. data/pdf2json-0.52-source/xpdf/pdfinfo +0 -0
  456. data/pdf2json-0.52-source/xpdf/pdfinfo.cc +387 -0
  457. data/pdf2json-0.52-source/xpdf/pdfinfo.o +0 -0
  458. data/pdf2json-0.52-source/xpdf/pdftoppm.cc +203 -0
  459. data/pdf2json-0.52-source/xpdf/pdftops +0 -0
  460. data/pdf2json-0.52-source/xpdf/pdftops.cc +344 -0
  461. data/pdf2json-0.52-source/xpdf/pdftops.o +0 -0
  462. data/pdf2json-0.52-source/xpdf/pdftotext +0 -0
  463. data/pdf2json-0.52-source/xpdf/pdftotext.cc +333 -0
  464. data/pdf2json-0.52-source/xpdf/pdftotext.o +0 -0
  465. data/pdf2json-0.52-source/xpdf/print.xbm +6 -0
  466. data/pdf2json-0.52-source/xpdf/printDis.xbm +6 -0
  467. data/pdf2json-0.52-source/xpdf/rightArrow.xbm +5 -0
  468. data/pdf2json-0.52-source/xpdf/rightArrowDis.xbm +5 -0
  469. data/pdf2json-0.52-source/xpdf/vms_make.com +129 -0
  470. data/pdf2json-0.52-source/xpdf/xpdf.cc +344 -0
  471. data/pdf2json-0.52-source/xpdf/xpdfIcon.xpm +62 -0
  472. data/pdf2json.gemspec +29 -0
  473. metadata +518 -0
@@ -0,0 +1,4627 @@
1
+ //========================================================================
2
+ //
3
+ // Stream.cc
4
+ //
5
+ // Copyright 1996-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 <stdio.h>
16
+ #include <stdlib.h>
17
+ #include <stddef.h>
18
+ #include <limits.h>
19
+ #ifndef WIN32
20
+ #include <unistd.h>
21
+ #endif
22
+ #include <string.h>
23
+ #include <ctype.h>
24
+ #include "gmem.h"
25
+ #include "gfile.h"
26
+ #include "config.h"
27
+ #include "Error.h"
28
+ #include "Object.h"
29
+ #include "Lexer.h"
30
+ #include "GfxState.h"
31
+ #include "Stream.h"
32
+ #include "JBIG2Stream.h"
33
+ #include "JPXStream.h"
34
+ #include "Stream-CCITT.h"
35
+
36
+ #ifdef __DJGPP__
37
+ static GBool setDJSYSFLAGS = gFalse;
38
+ #endif
39
+
40
+ #ifdef VMS
41
+ #ifdef __GNUC__
42
+ #define SEEK_SET 0
43
+ #define SEEK_CUR 1
44
+ #define SEEK_END 2
45
+ #endif
46
+ #endif
47
+
48
+ //------------------------------------------------------------------------
49
+ // Stream (base class)
50
+ //------------------------------------------------------------------------
51
+
52
+ Stream::Stream() {
53
+ ref = 1;
54
+ }
55
+
56
+ Stream::~Stream() {
57
+ }
58
+
59
+ void Stream::close() {
60
+ }
61
+
62
+ int Stream::getRawChar() {
63
+ error(-1, "Internal: called getRawChar() on non-predictor stream");
64
+ return EOF;
65
+ }
66
+
67
+ char *Stream::getLine(char *buf, int size) {
68
+ int i;
69
+ int c;
70
+
71
+ if (lookChar() == EOF)
72
+ return NULL;
73
+ for (i = 0; i < size - 1; ++i) {
74
+ c = getChar();
75
+ if (c == EOF || c == '\n')
76
+ break;
77
+ if (c == '\r') {
78
+ if ((c = lookChar()) == '\n')
79
+ getChar();
80
+ break;
81
+ }
82
+ buf[i] = c;
83
+ }
84
+ buf[i] = '\0';
85
+ return buf;
86
+ }
87
+
88
+ GString *Stream::getPSFilter(int psLevel, char *indent) {
89
+ return new GString();
90
+ }
91
+
92
+ Stream *Stream::addFilters(Object *dict) {
93
+ Object obj, obj2;
94
+ Object params, params2;
95
+ Stream *str;
96
+ int i;
97
+
98
+ str = this;
99
+ dict->dictLookup("Filter", &obj);
100
+ if (obj.isNull()) {
101
+ obj.free();
102
+ dict->dictLookup("F", &obj);
103
+ }
104
+ dict->dictLookup("DecodeParms", &params);
105
+ if (params.isNull()) {
106
+ params.free();
107
+ dict->dictLookup("DP", &params);
108
+ }
109
+ if (obj.isName()) {
110
+ str = makeFilter(obj.getName(), str, &params);
111
+ } else if (obj.isArray()) {
112
+ for (i = 0; i < obj.arrayGetLength(); ++i) {
113
+ obj.arrayGet(i, &obj2);
114
+ if (params.isArray())
115
+ params.arrayGet(i, &params2);
116
+ else
117
+ params2.initNull();
118
+ if (obj2.isName()) {
119
+ str = makeFilter(obj2.getName(), str, &params2);
120
+ } else {
121
+ error(getPos(), "Bad filter name");
122
+ str = new EOFStream(str);
123
+ }
124
+ obj2.free();
125
+ params2.free();
126
+ }
127
+ } else if (!obj.isNull()) {
128
+ error(getPos(), "Bad 'Filter' attribute in stream");
129
+ }
130
+ obj.free();
131
+ params.free();
132
+
133
+ return str;
134
+ }
135
+
136
+ Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
137
+ int pred; // parameters
138
+ int colors;
139
+ int bits;
140
+ int early;
141
+ int encoding;
142
+ GBool endOfLine, byteAlign, endOfBlock, black;
143
+ int columns, rows;
144
+ int colorXform;
145
+ Object globals, obj;
146
+
147
+ if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
148
+ str = new ASCIIHexStream(str);
149
+ } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
150
+ str = new ASCII85Stream(str);
151
+ } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
152
+ pred = 1;
153
+ columns = 1;
154
+ colors = 1;
155
+ bits = 8;
156
+ early = 1;
157
+ if (params->isDict()) {
158
+ params->dictLookup("Predictor", &obj);
159
+ if (obj.isInt())
160
+ pred = obj.getInt();
161
+ obj.free();
162
+ params->dictLookup("Columns", &obj);
163
+ if (obj.isInt())
164
+ columns = obj.getInt();
165
+ obj.free();
166
+ params->dictLookup("Colors", &obj);
167
+ if (obj.isInt())
168
+ colors = obj.getInt();
169
+ obj.free();
170
+ params->dictLookup("BitsPerComponent", &obj);
171
+ if (obj.isInt())
172
+ bits = obj.getInt();
173
+ obj.free();
174
+ params->dictLookup("EarlyChange", &obj);
175
+ if (obj.isInt())
176
+ early = obj.getInt();
177
+ obj.free();
178
+ }
179
+ str = new LZWStream(str, pred, columns, colors, bits, early);
180
+ } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
181
+ str = new RunLengthStream(str);
182
+ } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
183
+ encoding = 0;
184
+ endOfLine = gFalse;
185
+ byteAlign = gFalse;
186
+ columns = 1728;
187
+ rows = 0;
188
+ endOfBlock = gTrue;
189
+ black = gFalse;
190
+ if (params->isDict()) {
191
+ params->dictLookup("K", &obj);
192
+ if (obj.isInt()) {
193
+ encoding = obj.getInt();
194
+ }
195
+ obj.free();
196
+ params->dictLookup("EndOfLine", &obj);
197
+ if (obj.isBool()) {
198
+ endOfLine = obj.getBool();
199
+ }
200
+ obj.free();
201
+ params->dictLookup("EncodedByteAlign", &obj);
202
+ if (obj.isBool()) {
203
+ byteAlign = obj.getBool();
204
+ }
205
+ obj.free();
206
+ params->dictLookup("Columns", &obj);
207
+ if (obj.isInt()) {
208
+ columns = obj.getInt();
209
+ }
210
+ obj.free();
211
+ params->dictLookup("Rows", &obj);
212
+ if (obj.isInt()) {
213
+ rows = obj.getInt();
214
+ }
215
+ obj.free();
216
+ params->dictLookup("EndOfBlock", &obj);
217
+ if (obj.isBool()) {
218
+ endOfBlock = obj.getBool();
219
+ }
220
+ obj.free();
221
+ params->dictLookup("BlackIs1", &obj);
222
+ if (obj.isBool()) {
223
+ black = obj.getBool();
224
+ }
225
+ obj.free();
226
+ }
227
+ str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
228
+ columns, rows, endOfBlock, black);
229
+ } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
230
+ colorXform = -1;
231
+ if (params->isDict()) {
232
+ if (params->dictLookup("ColorTransform", &obj)->isInt()) {
233
+ colorXform = obj.getInt();
234
+ }
235
+ obj.free();
236
+ }
237
+ str = new DCTStream(str, colorXform);
238
+ } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
239
+ pred = 1;
240
+ columns = 1;
241
+ colors = 1;
242
+ bits = 8;
243
+ if (params->isDict()) {
244
+ params->dictLookup("Predictor", &obj);
245
+ if (obj.isInt())
246
+ pred = obj.getInt();
247
+ obj.free();
248
+ params->dictLookup("Columns", &obj);
249
+ if (obj.isInt())
250
+ columns = obj.getInt();
251
+ obj.free();
252
+ params->dictLookup("Colors", &obj);
253
+ if (obj.isInt())
254
+ colors = obj.getInt();
255
+ obj.free();
256
+ params->dictLookup("BitsPerComponent", &obj);
257
+ if (obj.isInt())
258
+ bits = obj.getInt();
259
+ obj.free();
260
+ }
261
+ str = new FlateStream(str, pred, columns, colors, bits);
262
+ } else if (!strcmp(name, "JBIG2Decode")) {
263
+ if (params->isDict()) {
264
+ params->dictLookup("JBIG2Globals", &globals);
265
+ }
266
+ str = new JBIG2Stream(str, &globals);
267
+ globals.free();
268
+ } else if (!strcmp(name, "JPXDecode")) {
269
+ str = new JPXStream(str);
270
+ } else {
271
+ error(getPos(), "Unknown filter '%s'", name);
272
+ str = new EOFStream(str);
273
+ }
274
+ return str;
275
+ }
276
+
277
+ //------------------------------------------------------------------------
278
+ // BaseStream
279
+ //------------------------------------------------------------------------
280
+
281
+ BaseStream::BaseStream(Object *dictA) {
282
+ dict = *dictA;
283
+ }
284
+
285
+ BaseStream::~BaseStream() {
286
+ dict.free();
287
+ }
288
+
289
+ //------------------------------------------------------------------------
290
+ // FilterStream
291
+ //------------------------------------------------------------------------
292
+
293
+ FilterStream::FilterStream(Stream *strA) {
294
+ str = strA;
295
+ }
296
+
297
+ FilterStream::~FilterStream() {
298
+ }
299
+
300
+ void FilterStream::close() {
301
+ str->close();
302
+ }
303
+
304
+ void FilterStream::setPos(Guint pos, int dir) {
305
+ error(-1, "Internal: called setPos() on FilterStream");
306
+ }
307
+
308
+ //------------------------------------------------------------------------
309
+ // ImageStream
310
+ //------------------------------------------------------------------------
311
+
312
+ ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
313
+ int imgLineSize;
314
+
315
+ str = strA;
316
+ width = widthA;
317
+ nComps = nCompsA;
318
+ nBits = nBitsA;
319
+
320
+ nVals = width * nComps;
321
+ if (nBits == 1) {
322
+ imgLineSize = (nVals + 7) & ~7;
323
+ } else {
324
+ imgLineSize = nVals;
325
+ }
326
+ imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
327
+ imgIdx = nVals;
328
+ }
329
+
330
+ ImageStream::~ImageStream() {
331
+ gfree(imgLine);
332
+ }
333
+
334
+ void ImageStream::reset() {
335
+ str->reset();
336
+ }
337
+
338
+ GBool ImageStream::getPixel(Guchar *pix) {
339
+ int i;
340
+
341
+ if (imgIdx >= nVals) {
342
+ getLine();
343
+ imgIdx = 0;
344
+ }
345
+ for (i = 0; i < nComps; ++i) {
346
+ pix[i] = imgLine[imgIdx++];
347
+ }
348
+ return gTrue;
349
+ }
350
+
351
+ Guchar *ImageStream::getLine() {
352
+ Gulong buf, bitMask;
353
+ int bits;
354
+ int c;
355
+ int i;
356
+
357
+ if (nBits == 1) {
358
+ for (i = 0; i < nVals; i += 8) {
359
+ c = str->getChar();
360
+ imgLine[i+0] = (Guchar)((c >> 7) & 1);
361
+ imgLine[i+1] = (Guchar)((c >> 6) & 1);
362
+ imgLine[i+2] = (Guchar)((c >> 5) & 1);
363
+ imgLine[i+3] = (Guchar)((c >> 4) & 1);
364
+ imgLine[i+4] = (Guchar)((c >> 3) & 1);
365
+ imgLine[i+5] = (Guchar)((c >> 2) & 1);
366
+ imgLine[i+6] = (Guchar)((c >> 1) & 1);
367
+ imgLine[i+7] = (Guchar)(c & 1);
368
+ }
369
+ } else if (nBits == 8) {
370
+ for (i = 0; i < nVals; ++i) {
371
+ imgLine[i] = str->getChar();
372
+ }
373
+ } else {
374
+ bitMask = (1 << nBits) - 1;
375
+ buf = 0;
376
+ bits = 0;
377
+ for (i = 0; i < nVals; ++i) {
378
+ if (bits < nBits) {
379
+ buf = (buf << 8) | (str->getChar() & 0xff);
380
+ bits += 8;
381
+ }
382
+ imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
383
+ bits -= nBits;
384
+ }
385
+ }
386
+ return imgLine;
387
+ }
388
+
389
+ void ImageStream::skipLine() {
390
+ int n, i;
391
+
392
+ n = (nVals * nBits + 7) >> 3;
393
+ for (i = 0; i < n; ++i) {
394
+ str->getChar();
395
+ }
396
+ }
397
+
398
+ //------------------------------------------------------------------------
399
+ // StreamPredictor
400
+ //------------------------------------------------------------------------
401
+
402
+ StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
403
+ int widthA, int nCompsA, int nBitsA) {
404
+ str = strA;
405
+ predictor = predictorA;
406
+ width = widthA;
407
+ nComps = nCompsA;
408
+ nBits = nBitsA;
409
+ predLine = NULL;
410
+ ok = gFalse;
411
+
412
+ nVals = width * nComps;
413
+ if (width <= 0 || nComps <= 0 || nBits <= 0 ||
414
+ nComps >= INT_MAX / nBits ||
415
+ width >= INT_MAX / nComps / nBits ||
416
+ nVals * nBits + 7 < 0) {
417
+ return;
418
+ }
419
+ pixBytes = (nComps * nBits + 7) >> 3;
420
+ rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
421
+ if (rowBytes <= 0) {
422
+ return;
423
+ }
424
+ predLine = (Guchar *)gmalloc(rowBytes);
425
+ memset(predLine, 0, rowBytes);
426
+ predIdx = rowBytes;
427
+
428
+ ok = gTrue;
429
+ }
430
+
431
+ StreamPredictor::~StreamPredictor() {
432
+ gfree(predLine);
433
+ }
434
+
435
+ int StreamPredictor::lookChar() {
436
+ if (predIdx >= rowBytes) {
437
+ if (!getNextLine()) {
438
+ return EOF;
439
+ }
440
+ }
441
+ return predLine[predIdx];
442
+ }
443
+
444
+ int StreamPredictor::getChar() {
445
+ if (predIdx >= rowBytes) {
446
+ if (!getNextLine()) {
447
+ return EOF;
448
+ }
449
+ }
450
+ return predLine[predIdx++];
451
+ }
452
+
453
+ GBool StreamPredictor::getNextLine() {
454
+ int curPred;
455
+ Guchar upLeftBuf[gfxColorMaxComps * 2 + 1];
456
+ int left, up, upLeft, p, pa, pb, pc;
457
+ int c;
458
+ Gulong inBuf, outBuf, bitMask;
459
+ int inBits, outBits;
460
+ int i, j, k, kk;
461
+
462
+ // get PNG optimum predictor number
463
+ if (predictor >= 10) {
464
+ if ((curPred = str->getRawChar()) == EOF) {
465
+ return gFalse;
466
+ }
467
+ curPred += 10;
468
+ } else {
469
+ curPred = predictor;
470
+ }
471
+
472
+ // read the raw line, apply PNG (byte) predictor
473
+ memset(upLeftBuf, 0, pixBytes + 1);
474
+ for (i = pixBytes; i < rowBytes; ++i) {
475
+ for (j = pixBytes; j > 0; --j) {
476
+ upLeftBuf[j] = upLeftBuf[j-1];
477
+ }
478
+ upLeftBuf[0] = predLine[i];
479
+ if ((c = str->getRawChar()) == EOF) {
480
+ if (i > pixBytes) {
481
+ // this ought to return false, but some (broken) PDF files
482
+ // contain truncated image data, and Adobe apparently reads the
483
+ // last partial line
484
+ break;
485
+ }
486
+ return gFalse;
487
+ }
488
+ switch (curPred) {
489
+ case 11: // PNG sub
490
+ predLine[i] = predLine[i - pixBytes] + (Guchar)c;
491
+ break;
492
+ case 12: // PNG up
493
+ predLine[i] = predLine[i] + (Guchar)c;
494
+ break;
495
+ case 13: // PNG average
496
+ predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
497
+ (Guchar)c;
498
+ break;
499
+ case 14: // PNG Paeth
500
+ left = predLine[i - pixBytes];
501
+ up = predLine[i];
502
+ upLeft = upLeftBuf[pixBytes];
503
+ p = left + up - upLeft;
504
+ if ((pa = p - left) < 0)
505
+ pa = -pa;
506
+ if ((pb = p - up) < 0)
507
+ pb = -pb;
508
+ if ((pc = p - upLeft) < 0)
509
+ pc = -pc;
510
+ if (pa <= pb && pa <= pc)
511
+ predLine[i] = left + (Guchar)c;
512
+ else if (pb <= pc)
513
+ predLine[i] = up + (Guchar)c;
514
+ else
515
+ predLine[i] = upLeft + (Guchar)c;
516
+ break;
517
+ case 10: // PNG none
518
+ default: // no predictor or TIFF predictor
519
+ predLine[i] = (Guchar)c;
520
+ break;
521
+ }
522
+ }
523
+
524
+ // apply TIFF (component) predictor
525
+ if (predictor == 2) {
526
+ if (nBits == 1) {
527
+ inBuf = predLine[pixBytes - 1];
528
+ for (i = pixBytes; i < rowBytes; i += 8) {
529
+ // 1-bit add is just xor
530
+ inBuf = (inBuf << 8) | predLine[i];
531
+ predLine[i] ^= inBuf >> nComps;
532
+ }
533
+ } else if (nBits == 8) {
534
+ for (i = pixBytes; i < rowBytes; ++i) {
535
+ predLine[i] += predLine[i - nComps];
536
+ }
537
+ } else {
538
+ memset(upLeftBuf, 0, nComps + 1);
539
+ bitMask = (1 << nBits) - 1;
540
+ inBuf = outBuf = 0;
541
+ inBits = outBits = 0;
542
+ j = k = pixBytes;
543
+ for (i = 0; i < width; ++i) {
544
+ for (kk = 0; kk < nComps; ++kk) {
545
+ if (inBits < nBits) {
546
+ inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
547
+ inBits += 8;
548
+ }
549
+ upLeftBuf[kk] = (Guchar)((upLeftBuf[kk] +
550
+ (inBuf >> (inBits - nBits))) & bitMask);
551
+ inBits -= nBits;
552
+ outBuf = (outBuf << nBits) | upLeftBuf[kk];
553
+ outBits += nBits;
554
+ if (outBits >= 8) {
555
+ predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
556
+ outBits -= 8;
557
+ }
558
+ }
559
+ }
560
+ if (outBits > 0) {
561
+ predLine[k++] = (Guchar)((outBuf << (8 - outBits)) +
562
+ (inBuf & ((1 << (8 - outBits)) - 1)));
563
+ }
564
+ }
565
+ }
566
+
567
+ // reset to start of line
568
+ predIdx = pixBytes;
569
+
570
+ return gTrue;
571
+ }
572
+
573
+ //------------------------------------------------------------------------
574
+ // FileStream
575
+ //------------------------------------------------------------------------
576
+
577
+ FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA,
578
+ Guint lengthA, Object *dictA):
579
+ BaseStream(dictA) {
580
+ f = fA;
581
+ start = startA;
582
+ limited = limitedA;
583
+ length = lengthA;
584
+ bufPtr = bufEnd = buf;
585
+ bufPos = start;
586
+ savePos = 0;
587
+ saved = gFalse;
588
+ }
589
+
590
+ FileStream::~FileStream() {
591
+ close();
592
+ }
593
+
594
+ Stream *FileStream::makeSubStream(Guint startA, GBool limitedA,
595
+ Guint lengthA, Object *dictA) {
596
+ return new FileStream(f, startA, limitedA, lengthA, dictA);
597
+ }
598
+
599
+ void FileStream::reset() {
600
+ #if HAVE_FSEEKO
601
+ savePos = (Guint)ftello(f);
602
+ fseeko(f, start, SEEK_SET);
603
+ #elif HAVE_FSEEK64
604
+ savePos = (Guint)ftell64(f);
605
+ fseek64(f, start, SEEK_SET);
606
+ #else
607
+ savePos = (Guint)ftell(f);
608
+ fseek(f, start, SEEK_SET);
609
+ #endif
610
+ saved = gTrue;
611
+ bufPtr = bufEnd = buf;
612
+ bufPos = start;
613
+ }
614
+
615
+ void FileStream::close() {
616
+ if (saved) {
617
+ #if HAVE_FSEEKO
618
+ fseeko(f, savePos, SEEK_SET);
619
+ #elif HAVE_FSEEK64
620
+ fseek64(f, savePos, SEEK_SET);
621
+ #else
622
+ fseek(f, savePos, SEEK_SET);
623
+ #endif
624
+ saved = gFalse;
625
+ }
626
+ }
627
+
628
+ GBool FileStream::fillBuf() {
629
+ int n;
630
+
631
+ bufPos += bufEnd - buf;
632
+ bufPtr = bufEnd = buf;
633
+ if (limited && bufPos >= start + length) {
634
+ return gFalse;
635
+ }
636
+ if (limited && bufPos + fileStreamBufSize > start + length) {
637
+ n = start + length - bufPos;
638
+ } else {
639
+ n = fileStreamBufSize;
640
+ }
641
+ n = fread(buf, 1, n, f);
642
+ bufEnd = buf + n;
643
+ if (bufPtr >= bufEnd) {
644
+ return gFalse;
645
+ }
646
+ return gTrue;
647
+ }
648
+
649
+ void FileStream::setPos(Guint pos, int dir) {
650
+ Guint size;
651
+
652
+ if (dir >= 0) {
653
+ #if HAVE_FSEEKO
654
+ fseeko(f, pos, SEEK_SET);
655
+ #elif HAVE_FSEEK64
656
+ fseek64(f, pos, SEEK_SET);
657
+ #else
658
+ fseek(f, pos, SEEK_SET);
659
+ #endif
660
+ bufPos = pos;
661
+ } else {
662
+ #if HAVE_FSEEKO
663
+ fseeko(f, 0, SEEK_END);
664
+ size = (Guint)ftello(f);
665
+ #elif HAVE_FSEEK64
666
+ fseek64(f, 0, SEEK_END);
667
+ size = (Guint)ftell64(f);
668
+ #else
669
+ fseek(f, 0, SEEK_END);
670
+ size = (Guint)ftell(f);
671
+ #endif
672
+ if (pos > size)
673
+ pos = (Guint)size;
674
+ #ifdef __CYGWIN32__
675
+ //~ work around a bug in cygwin's implementation of fseek
676
+ rewind(f);
677
+ #endif
678
+ #if HAVE_FSEEKO
679
+ fseeko(f, -(int)pos, SEEK_END);
680
+ bufPos = (Guint)ftello(f);
681
+ #elif HAVE_FSEEK64
682
+ fseek64(f, -(int)pos, SEEK_END);
683
+ bufPos = (Guint)ftell64(f);
684
+ #else
685
+ fseek(f, -(int)pos, SEEK_END);
686
+ bufPos = (Guint)ftell(f);
687
+ #endif
688
+ }
689
+ bufPtr = bufEnd = buf;
690
+ }
691
+
692
+ void FileStream::moveStart(int delta) {
693
+ start += delta;
694
+ bufPtr = bufEnd = buf;
695
+ bufPos = start;
696
+ }
697
+
698
+ //------------------------------------------------------------------------
699
+ // MemStream
700
+ //------------------------------------------------------------------------
701
+
702
+ MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA):
703
+ BaseStream(dictA) {
704
+ buf = bufA;
705
+ start = startA;
706
+ length = lengthA;
707
+ bufEnd = buf + start + length;
708
+ bufPtr = buf + start;
709
+ needFree = gFalse;
710
+ }
711
+
712
+ MemStream::~MemStream() {
713
+ if (needFree) {
714
+ gfree(buf);
715
+ }
716
+ }
717
+
718
+ Stream *MemStream::makeSubStream(Guint startA, GBool limited,
719
+ Guint lengthA, Object *dictA) {
720
+ MemStream *subStr;
721
+ Guint newLength;
722
+
723
+ if (!limited || startA + lengthA > start + length) {
724
+ newLength = start + length - startA;
725
+ } else {
726
+ newLength = lengthA;
727
+ }
728
+ subStr = new MemStream(buf, startA, newLength, dictA);
729
+ return subStr;
730
+ }
731
+
732
+ void MemStream::reset() {
733
+ bufPtr = buf + start;
734
+ }
735
+
736
+ void MemStream::close() {
737
+ }
738
+
739
+ void MemStream::setPos(Guint pos, int dir) {
740
+ Guint i;
741
+
742
+ if (dir >= 0) {
743
+ i = pos;
744
+ } else {
745
+ i = start + length - pos;
746
+ }
747
+ if (i < start) {
748
+ i = start;
749
+ } else if (i > start + length) {
750
+ i = start + length;
751
+ }
752
+ bufPtr = buf + i;
753
+ }
754
+
755
+ void MemStream::moveStart(int delta) {
756
+ start += delta;
757
+ length -= delta;
758
+ bufPtr = buf + start;
759
+ }
760
+
761
+ //------------------------------------------------------------------------
762
+ // EmbedStream
763
+ //------------------------------------------------------------------------
764
+
765
+ EmbedStream::EmbedStream(Stream *strA, Object *dictA,
766
+ GBool limitedA, Guint lengthA):
767
+ BaseStream(dictA) {
768
+ str = strA;
769
+ limited = limitedA;
770
+ length = lengthA;
771
+ }
772
+
773
+ EmbedStream::~EmbedStream() {
774
+ }
775
+
776
+ Stream *EmbedStream::makeSubStream(Guint start, GBool limitedA,
777
+ Guint lengthA, Object *dictA) {
778
+ error(-1, "Internal: called makeSubStream() on EmbedStream");
779
+ return NULL;
780
+ }
781
+
782
+ int EmbedStream::getChar() {
783
+ if (limited && !length) {
784
+ return EOF;
785
+ }
786
+ --length;
787
+ return str->getChar();
788
+ }
789
+
790
+ int EmbedStream::lookChar() {
791
+ if (limited && !length) {
792
+ return EOF;
793
+ }
794
+ return str->lookChar();
795
+ }
796
+
797
+ void EmbedStream::setPos(Guint pos, int dir) {
798
+ error(-1, "Internal: called setPos() on EmbedStream");
799
+ }
800
+
801
+ Guint EmbedStream::getStart() {
802
+ error(-1, "Internal: called getStart() on EmbedStream");
803
+ return 0;
804
+ }
805
+
806
+ void EmbedStream::moveStart(int delta) {
807
+ error(-1, "Internal: called moveStart() on EmbedStream");
808
+ }
809
+
810
+ //------------------------------------------------------------------------
811
+ // ASCIIHexStream
812
+ //------------------------------------------------------------------------
813
+
814
+ ASCIIHexStream::ASCIIHexStream(Stream *strA):
815
+ FilterStream(strA) {
816
+ buf = EOF;
817
+ eof = gFalse;
818
+ }
819
+
820
+ ASCIIHexStream::~ASCIIHexStream() {
821
+ delete str;
822
+ }
823
+
824
+ void ASCIIHexStream::reset() {
825
+ str->reset();
826
+ buf = EOF;
827
+ eof = gFalse;
828
+ }
829
+
830
+ int ASCIIHexStream::lookChar() {
831
+ int c1, c2, x;
832
+
833
+ if (buf != EOF)
834
+ return buf;
835
+ if (eof) {
836
+ buf = EOF;
837
+ return EOF;
838
+ }
839
+ do {
840
+ c1 = str->getChar();
841
+ } while (isspace(c1));
842
+ if (c1 == '>') {
843
+ eof = gTrue;
844
+ buf = EOF;
845
+ return buf;
846
+ }
847
+ do {
848
+ c2 = str->getChar();
849
+ } while (isspace(c2));
850
+ if (c2 == '>') {
851
+ eof = gTrue;
852
+ c2 = '0';
853
+ }
854
+ if (c1 >= '0' && c1 <= '9') {
855
+ x = (c1 - '0') << 4;
856
+ } else if (c1 >= 'A' && c1 <= 'F') {
857
+ x = (c1 - 'A' + 10) << 4;
858
+ } else if (c1 >= 'a' && c1 <= 'f') {
859
+ x = (c1 - 'a' + 10) << 4;
860
+ } else if (c1 == EOF) {
861
+ eof = gTrue;
862
+ x = 0;
863
+ } else {
864
+ error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
865
+ x = 0;
866
+ }
867
+ if (c2 >= '0' && c2 <= '9') {
868
+ x += c2 - '0';
869
+ } else if (c2 >= 'A' && c2 <= 'F') {
870
+ x += c2 - 'A' + 10;
871
+ } else if (c2 >= 'a' && c2 <= 'f') {
872
+ x += c2 - 'a' + 10;
873
+ } else if (c2 == EOF) {
874
+ eof = gTrue;
875
+ x = 0;
876
+ } else {
877
+ error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
878
+ }
879
+ buf = x & 0xff;
880
+ return buf;
881
+ }
882
+
883
+ GString *ASCIIHexStream::getPSFilter(int psLevel, char *indent) {
884
+ GString *s;
885
+
886
+ if (psLevel < 2) {
887
+ return NULL;
888
+ }
889
+ if (!(s = str->getPSFilter(psLevel, indent))) {
890
+ return NULL;
891
+ }
892
+ s->append(indent)->append("/ASCIIHexDecode filter\n");
893
+ return s;
894
+ }
895
+
896
+ GBool ASCIIHexStream::isBinary(GBool last) {
897
+ return str->isBinary(gFalse);
898
+ }
899
+
900
+ //------------------------------------------------------------------------
901
+ // ASCII85Stream
902
+ //------------------------------------------------------------------------
903
+
904
+ ASCII85Stream::ASCII85Stream(Stream *strA):
905
+ FilterStream(strA) {
906
+ index = n = 0;
907
+ eof = gFalse;
908
+ }
909
+
910
+ ASCII85Stream::~ASCII85Stream() {
911
+ delete str;
912
+ }
913
+
914
+ void ASCII85Stream::reset() {
915
+ str->reset();
916
+ index = n = 0;
917
+ eof = gFalse;
918
+ }
919
+
920
+ int ASCII85Stream::lookChar() {
921
+ int k;
922
+ Gulong t;
923
+
924
+ if (index >= n) {
925
+ if (eof)
926
+ return EOF;
927
+ index = 0;
928
+ do {
929
+ c[0] = str->getChar();
930
+ } while (Lexer::isSpace(c[0]));
931
+ if (c[0] == '~' || c[0] == EOF) {
932
+ eof = gTrue;
933
+ n = 0;
934
+ return EOF;
935
+ } else if (c[0] == 'z') {
936
+ b[0] = b[1] = b[2] = b[3] = 0;
937
+ n = 4;
938
+ } else {
939
+ for (k = 1; k < 5; ++k) {
940
+ do {
941
+ c[k] = str->getChar();
942
+ } while (Lexer::isSpace(c[k]));
943
+ if (c[k] == '~' || c[k] == EOF)
944
+ break;
945
+ }
946
+ n = k - 1;
947
+ if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
948
+ for (++k; k < 5; ++k)
949
+ c[k] = 0x21 + 84;
950
+ eof = gTrue;
951
+ }
952
+ t = 0;
953
+ for (k = 0; k < 5; ++k)
954
+ t = t * 85 + (c[k] - 0x21);
955
+ for (k = 3; k >= 0; --k) {
956
+ b[k] = (int)(t & 0xff);
957
+ t >>= 8;
958
+ }
959
+ }
960
+ }
961
+ return b[index];
962
+ }
963
+
964
+ GString *ASCII85Stream::getPSFilter(int psLevel, char *indent) {
965
+ GString *s;
966
+
967
+ if (psLevel < 2) {
968
+ return NULL;
969
+ }
970
+ if (!(s = str->getPSFilter(psLevel, indent))) {
971
+ return NULL;
972
+ }
973
+ s->append(indent)->append("/ASCII85Decode filter\n");
974
+ return s;
975
+ }
976
+
977
+ GBool ASCII85Stream::isBinary(GBool last) {
978
+ return str->isBinary(gFalse);
979
+ }
980
+
981
+ //------------------------------------------------------------------------
982
+ // LZWStream
983
+ //------------------------------------------------------------------------
984
+
985
+ LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
986
+ int bits, int earlyA):
987
+ FilterStream(strA) {
988
+ if (predictor != 1) {
989
+ pred = new StreamPredictor(this, predictor, columns, colors, bits);
990
+ if (!pred->isOk()) {
991
+ delete pred;
992
+ pred = NULL;
993
+ }
994
+ } else {
995
+ pred = NULL;
996
+ }
997
+ early = earlyA;
998
+ eof = gFalse;
999
+ inputBits = 0;
1000
+ clearTable();
1001
+ }
1002
+
1003
+ LZWStream::~LZWStream() {
1004
+ if (pred) {
1005
+ delete pred;
1006
+ }
1007
+ delete str;
1008
+ }
1009
+
1010
+ int LZWStream::getChar() {
1011
+ if (pred) {
1012
+ return pred->getChar();
1013
+ }
1014
+ if (eof) {
1015
+ return EOF;
1016
+ }
1017
+ if (seqIndex >= seqLength) {
1018
+ if (!processNextCode()) {
1019
+ return EOF;
1020
+ }
1021
+ }
1022
+ return seqBuf[seqIndex++];
1023
+ }
1024
+
1025
+ int LZWStream::lookChar() {
1026
+ if (pred) {
1027
+ return pred->lookChar();
1028
+ }
1029
+ if (eof) {
1030
+ return EOF;
1031
+ }
1032
+ if (seqIndex >= seqLength) {
1033
+ if (!processNextCode()) {
1034
+ return EOF;
1035
+ }
1036
+ }
1037
+ return seqBuf[seqIndex];
1038
+ }
1039
+
1040
+ int LZWStream::getRawChar() {
1041
+ if (eof) {
1042
+ return EOF;
1043
+ }
1044
+ if (seqIndex >= seqLength) {
1045
+ if (!processNextCode()) {
1046
+ return EOF;
1047
+ }
1048
+ }
1049
+ return seqBuf[seqIndex++];
1050
+ }
1051
+
1052
+ void LZWStream::reset() {
1053
+ str->reset();
1054
+ eof = gFalse;
1055
+ inputBits = 0;
1056
+ clearTable();
1057
+ }
1058
+
1059
+ GBool LZWStream::processNextCode() {
1060
+ int code;
1061
+ int nextLength;
1062
+ int i, j;
1063
+
1064
+ // check for EOF
1065
+ if (eof) {
1066
+ return gFalse;
1067
+ }
1068
+
1069
+ // check for eod and clear-table codes
1070
+ start:
1071
+ code = getCode();
1072
+ if (code == EOF || code == 257) {
1073
+ eof = gTrue;
1074
+ return gFalse;
1075
+ }
1076
+ if (code == 256) {
1077
+ clearTable();
1078
+ goto start;
1079
+ }
1080
+ if (nextCode >= 4097) {
1081
+ error(getPos(), "Bad LZW stream - expected clear-table code");
1082
+ clearTable();
1083
+ }
1084
+
1085
+ // process the next code
1086
+ nextLength = seqLength + 1;
1087
+ if (code < 256) {
1088
+ seqBuf[0] = code;
1089
+ seqLength = 1;
1090
+ } else if (code < nextCode) {
1091
+ seqLength = table[code].length;
1092
+ for (i = seqLength - 1, j = code; i > 0; --i) {
1093
+ seqBuf[i] = table[j].tail;
1094
+ j = table[j].head;
1095
+ }
1096
+ seqBuf[0] = j;
1097
+ } else if (code == nextCode) {
1098
+ seqBuf[seqLength] = newChar;
1099
+ ++seqLength;
1100
+ } else {
1101
+ error(getPos(), "Bad LZW stream - unexpected code");
1102
+ eof = gTrue;
1103
+ return gFalse;
1104
+ }
1105
+ newChar = seqBuf[0];
1106
+ if (first) {
1107
+ first = gFalse;
1108
+ } else {
1109
+ table[nextCode].length = nextLength;
1110
+ table[nextCode].head = prevCode;
1111
+ table[nextCode].tail = newChar;
1112
+ ++nextCode;
1113
+ if (nextCode + early == 512)
1114
+ nextBits = 10;
1115
+ else if (nextCode + early == 1024)
1116
+ nextBits = 11;
1117
+ else if (nextCode + early == 2048)
1118
+ nextBits = 12;
1119
+ }
1120
+ prevCode = code;
1121
+
1122
+ // reset buffer
1123
+ seqIndex = 0;
1124
+
1125
+ return gTrue;
1126
+ }
1127
+
1128
+ void LZWStream::clearTable() {
1129
+ nextCode = 258;
1130
+ nextBits = 9;
1131
+ seqIndex = seqLength = 0;
1132
+ first = gTrue;
1133
+ }
1134
+
1135
+ int LZWStream::getCode() {
1136
+ int c;
1137
+ int code;
1138
+
1139
+ while (inputBits < nextBits) {
1140
+ if ((c = str->getChar()) == EOF)
1141
+ return EOF;
1142
+ inputBuf = (inputBuf << 8) | (c & 0xff);
1143
+ inputBits += 8;
1144
+ }
1145
+ code = (inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1);
1146
+ inputBits -= nextBits;
1147
+ return code;
1148
+ }
1149
+
1150
+ GString *LZWStream::getPSFilter(int psLevel, char *indent) {
1151
+ GString *s;
1152
+
1153
+ if (psLevel < 2 || pred) {
1154
+ return NULL;
1155
+ }
1156
+ if (!(s = str->getPSFilter(psLevel, indent))) {
1157
+ return NULL;
1158
+ }
1159
+ s->append(indent)->append("<< ");
1160
+ if (!early) {
1161
+ s->append("/EarlyChange 0 ");
1162
+ }
1163
+ s->append(">> /LZWDecode filter\n");
1164
+ return s;
1165
+ }
1166
+
1167
+ GBool LZWStream::isBinary(GBool last) {
1168
+ return str->isBinary(gTrue);
1169
+ }
1170
+
1171
+ //------------------------------------------------------------------------
1172
+ // RunLengthStream
1173
+ //------------------------------------------------------------------------
1174
+
1175
+ RunLengthStream::RunLengthStream(Stream *strA):
1176
+ FilterStream(strA) {
1177
+ bufPtr = bufEnd = buf;
1178
+ eof = gFalse;
1179
+ }
1180
+
1181
+ RunLengthStream::~RunLengthStream() {
1182
+ delete str;
1183
+ }
1184
+
1185
+ void RunLengthStream::reset() {
1186
+ str->reset();
1187
+ bufPtr = bufEnd = buf;
1188
+ eof = gFalse;
1189
+ }
1190
+
1191
+ GString *RunLengthStream::getPSFilter(int psLevel, char *indent) {
1192
+ GString *s;
1193
+
1194
+ if (psLevel < 2) {
1195
+ return NULL;
1196
+ }
1197
+ if (!(s = str->getPSFilter(psLevel, indent))) {
1198
+ return NULL;
1199
+ }
1200
+ s->append(indent)->append("/RunLengthDecode filter\n");
1201
+ return s;
1202
+ }
1203
+
1204
+ GBool RunLengthStream::isBinary(GBool last) {
1205
+ return str->isBinary(gTrue);
1206
+ }
1207
+
1208
+ GBool RunLengthStream::fillBuf() {
1209
+ int c;
1210
+ int n, i;
1211
+
1212
+ if (eof)
1213
+ return gFalse;
1214
+ c = str->getChar();
1215
+ if (c == 0x80 || c == EOF) {
1216
+ eof = gTrue;
1217
+ return gFalse;
1218
+ }
1219
+ if (c < 0x80) {
1220
+ n = c + 1;
1221
+ for (i = 0; i < n; ++i)
1222
+ buf[i] = (char)str->getChar();
1223
+ } else {
1224
+ n = 0x101 - c;
1225
+ c = str->getChar();
1226
+ for (i = 0; i < n; ++i)
1227
+ buf[i] = (char)c;
1228
+ }
1229
+ bufPtr = buf;
1230
+ bufEnd = buf + n;
1231
+ return gTrue;
1232
+ }
1233
+
1234
+ //------------------------------------------------------------------------
1235
+ // CCITTFaxStream
1236
+ //------------------------------------------------------------------------
1237
+
1238
+ CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
1239
+ GBool byteAlignA, int columnsA, int rowsA,
1240
+ GBool endOfBlockA, GBool blackA):
1241
+ FilterStream(strA) {
1242
+ encoding = encodingA;
1243
+ endOfLine = endOfLineA;
1244
+ byteAlign = byteAlignA;
1245
+ columns = columnsA;
1246
+ if (columns < 1) {
1247
+ columns = 1;
1248
+ }
1249
+ if (columns + 4 <= 0) {
1250
+ columns = INT_MAX - 4;
1251
+ }
1252
+ rows = rowsA;
1253
+ endOfBlock = endOfBlockA;
1254
+ black = blackA;
1255
+ refLine = (short *)gmallocn(columns + 3, sizeof(short));
1256
+ codingLine = (short *)gmallocn(columns + 2, sizeof(short));
1257
+
1258
+ eof = gFalse;
1259
+ row = 0;
1260
+ nextLine2D = encoding < 0;
1261
+ inputBits = 0;
1262
+ codingLine[0] = 0;
1263
+ codingLine[1] = refLine[2] = columns;
1264
+ a0 = 1;
1265
+
1266
+ buf = EOF;
1267
+ }
1268
+
1269
+ CCITTFaxStream::~CCITTFaxStream() {
1270
+ delete str;
1271
+ gfree(refLine);
1272
+ gfree(codingLine);
1273
+ }
1274
+
1275
+ void CCITTFaxStream::reset() {
1276
+ short code1;
1277
+
1278
+ str->reset();
1279
+ eof = gFalse;
1280
+ row = 0;
1281
+ nextLine2D = encoding < 0;
1282
+ inputBits = 0;
1283
+ codingLine[0] = 0;
1284
+ codingLine[1] = columns;
1285
+ a0 = 1;
1286
+ buf = EOF;
1287
+
1288
+ // skip any initial zero bits and end-of-line marker, and get the 2D
1289
+ // encoding tag
1290
+ while ((code1 = lookBits(12)) == 0) {
1291
+ eatBits(1);
1292
+ }
1293
+ if (code1 == 0x001) {
1294
+ eatBits(12);
1295
+ }
1296
+ if (encoding > 0) {
1297
+ nextLine2D = !lookBits(1);
1298
+ eatBits(1);
1299
+ }
1300
+ }
1301
+
1302
+ int CCITTFaxStream::lookChar() {
1303
+ short code1, code2, code3;
1304
+ int a0New;
1305
+ GBool err, gotEOL;
1306
+ int ret;
1307
+ int bits, i;
1308
+
1309
+ // if at eof just return EOF
1310
+ if (eof && codingLine[a0] >= columns) {
1311
+ return EOF;
1312
+ }
1313
+
1314
+ // read the next row
1315
+ err = gFalse;
1316
+ if (codingLine[a0] >= columns) {
1317
+
1318
+ // 2-D encoding
1319
+ if (nextLine2D) {
1320
+ // state:
1321
+ // a0New = current position in coding line (0 <= a0New <= columns)
1322
+ // codingLine[a0] = last change in coding line
1323
+ // (black-to-white if a0 is even,
1324
+ // white-to-black if a0 is odd)
1325
+ // refLine[b1] = next change in reference line of opposite color
1326
+ // to a0
1327
+ // invariants:
1328
+ // 0 <= codingLine[a0] <= a0New
1329
+ // <= refLine[b1] <= refLine[b1+1] <= columns
1330
+ // 0 <= a0 <= columns+1
1331
+ // refLine[0] = 0
1332
+ // refLine[n] = refLine[n+1] = columns
1333
+ // -- for some 1 <= n <= columns+1
1334
+ // end condition:
1335
+ // 0 = codingLine[0] <= codingLine[1] < codingLine[2] < ...
1336
+ // < codingLine[n-1] < codingLine[n] = columns
1337
+ // -- where 1 <= n <= columns+1
1338
+ for (i = 0; codingLine[i] < columns; ++i) {
1339
+ refLine[i] = codingLine[i];
1340
+ }
1341
+ refLine[i] = refLine[i + 1] = columns;
1342
+ b1 = 1;
1343
+ a0New = codingLine[a0 = 0] = 0;
1344
+ do {
1345
+ code1 = getTwoDimCode();
1346
+ switch (code1) {
1347
+ case twoDimPass:
1348
+ if (refLine[b1] < columns) {
1349
+ a0New = refLine[b1 + 1];
1350
+ b1 += 2;
1351
+ }
1352
+ break;
1353
+ case twoDimHoriz:
1354
+ if ((a0 & 1) == 0) {
1355
+ code1 = code2 = 0;
1356
+ do {
1357
+ code1 += code3 = getWhiteCode();
1358
+ } while (code3 >= 64);
1359
+ do {
1360
+ code2 += code3 = getBlackCode();
1361
+ } while (code3 >= 64);
1362
+ } else {
1363
+ code1 = code2 = 0;
1364
+ do {
1365
+ code1 += code3 = getBlackCode();
1366
+ } while (code3 >= 64);
1367
+ do {
1368
+ code2 += code3 = getWhiteCode();
1369
+ } while (code3 >= 64);
1370
+ }
1371
+ if (code1 > 0 || code2 > 0) {
1372
+ if (a0New + code1 <= columns) {
1373
+ codingLine[a0 + 1] = a0New + code1;
1374
+ } else {
1375
+ codingLine[a0 + 1] = columns;
1376
+ }
1377
+ ++a0;
1378
+ if (codingLine[a0] + code2 <= columns) {
1379
+ codingLine[a0 + 1] = codingLine[a0] + code2;
1380
+ } else {
1381
+ codingLine[a0 + 1] = columns;
1382
+ }
1383
+ ++a0;
1384
+ a0New = codingLine[a0];
1385
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
1386
+ b1 += 2;
1387
+ }
1388
+ }
1389
+ break;
1390
+ case twoDimVert0:
1391
+ if (refLine[b1] < columns) {
1392
+ a0New = codingLine[++a0] = refLine[b1];
1393
+ ++b1;
1394
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
1395
+ b1 += 2;
1396
+ }
1397
+ } else {
1398
+ a0New = codingLine[++a0] = columns;
1399
+ }
1400
+ break;
1401
+ case twoDimVertR1:
1402
+ if (refLine[b1] + 1 < columns) {
1403
+ a0New = codingLine[++a0] = refLine[b1] + 1;
1404
+ ++b1;
1405
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
1406
+ b1 += 2;
1407
+ }
1408
+ } else {
1409
+ a0New = codingLine[++a0] = columns;
1410
+ }
1411
+ break;
1412
+ case twoDimVertL1:
1413
+ if (refLine[b1] - 1 > a0New || (a0 == 0 && refLine[b1] == 1)) {
1414
+ a0New = codingLine[++a0] = refLine[b1] - 1;
1415
+ --b1;
1416
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
1417
+ b1 += 2;
1418
+ }
1419
+ }
1420
+ break;
1421
+ case twoDimVertR2:
1422
+ if (refLine[b1] + 2 < columns) {
1423
+ a0New = codingLine[++a0] = refLine[b1] + 2;
1424
+ ++b1;
1425
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
1426
+ b1 += 2;
1427
+ }
1428
+ } else {
1429
+ a0New = codingLine[++a0] = columns;
1430
+ }
1431
+ break;
1432
+ case twoDimVertL2:
1433
+ if (refLine[b1] - 2 > a0New || (a0 == 0 && refLine[b1] == 2)) {
1434
+ a0New = codingLine[++a0] = refLine[b1] - 2;
1435
+ --b1;
1436
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
1437
+ b1 += 2;
1438
+ }
1439
+ }
1440
+ break;
1441
+ case twoDimVertR3:
1442
+ if (refLine[b1] + 3 < columns) {
1443
+ a0New = codingLine[++a0] = refLine[b1] + 3;
1444
+ ++b1;
1445
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
1446
+ b1 += 2;
1447
+ }
1448
+ } else {
1449
+ a0New = codingLine[++a0] = columns;
1450
+ }
1451
+ break;
1452
+ case twoDimVertL3:
1453
+ if (refLine[b1] - 3 > a0New || (a0 == 0 && refLine[b1] == 3)) {
1454
+ a0New = codingLine[++a0] = refLine[b1] - 3;
1455
+ --b1;
1456
+ while (refLine[b1] <= a0New && refLine[b1] < columns) {
1457
+ b1 += 2;
1458
+ }
1459
+ }
1460
+ break;
1461
+ case EOF:
1462
+ eof = gTrue;
1463
+ codingLine[a0 = 0] = columns;
1464
+ return EOF;
1465
+ default:
1466
+ error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
1467
+ err = gTrue;
1468
+ break;
1469
+ }
1470
+ } while (codingLine[a0] < columns);
1471
+
1472
+ // 1-D encoding
1473
+ } else {
1474
+ codingLine[a0 = 0] = 0;
1475
+ while (1) {
1476
+ code1 = 0;
1477
+ do {
1478
+ code1 += code3 = getWhiteCode();
1479
+ } while (code3 >= 64);
1480
+ codingLine[a0+1] = codingLine[a0] + code1;
1481
+ ++a0;
1482
+ if (codingLine[a0] >= columns) {
1483
+ break;
1484
+ }
1485
+ code2 = 0;
1486
+ do {
1487
+ code2 += code3 = getBlackCode();
1488
+ } while (code3 >= 64);
1489
+ codingLine[a0+1] = codingLine[a0] + code2;
1490
+ ++a0;
1491
+ if (codingLine[a0] >= columns) {
1492
+ break;
1493
+ }
1494
+ }
1495
+ }
1496
+
1497
+ if (codingLine[a0] != columns) {
1498
+ error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
1499
+ // force the row to be the correct length
1500
+ while (codingLine[a0] > columns) {
1501
+ --a0;
1502
+ }
1503
+ codingLine[++a0] = columns;
1504
+ err = gTrue;
1505
+ }
1506
+
1507
+ // byte-align the row
1508
+ if (byteAlign) {
1509
+ inputBits &= ~7;
1510
+ }
1511
+
1512
+ // check for end-of-line marker, skipping over any extra zero bits
1513
+ gotEOL = gFalse;
1514
+ if (!endOfBlock && row == rows - 1) {
1515
+ eof = gTrue;
1516
+ } else {
1517
+ code1 = lookBits(12);
1518
+ while (code1 == 0) {
1519
+ eatBits(1);
1520
+ code1 = lookBits(12);
1521
+ }
1522
+ if (code1 == 0x001) {
1523
+ eatBits(12);
1524
+ gotEOL = gTrue;
1525
+ } else if (code1 == EOF) {
1526
+ eof = gTrue;
1527
+ }
1528
+ }
1529
+
1530
+ // get 2D encoding tag
1531
+ if (!eof && encoding > 0) {
1532
+ nextLine2D = !lookBits(1);
1533
+ eatBits(1);
1534
+ }
1535
+
1536
+ // check for end-of-block marker
1537
+ if (endOfBlock && gotEOL) {
1538
+ code1 = lookBits(12);
1539
+ if (code1 == 0x001) {
1540
+ eatBits(12);
1541
+ if (encoding > 0) {
1542
+ lookBits(1);
1543
+ eatBits(1);
1544
+ }
1545
+ if (encoding >= 0) {
1546
+ for (i = 0; i < 4; ++i) {
1547
+ code1 = lookBits(12);
1548
+ if (code1 != 0x001) {
1549
+ error(getPos(), "Bad RTC code in CCITTFax stream");
1550
+ }
1551
+ eatBits(12);
1552
+ if (encoding > 0) {
1553
+ lookBits(1);
1554
+ eatBits(1);
1555
+ }
1556
+ }
1557
+ }
1558
+ eof = gTrue;
1559
+ }
1560
+
1561
+ // look for an end-of-line marker after an error -- we only do
1562
+ // this if we know the stream contains end-of-line markers because
1563
+ // the "just plow on" technique tends to work better otherwise
1564
+ } else if (err && endOfLine) {
1565
+ do {
1566
+ if (code1 == EOF) {
1567
+ eof = gTrue;
1568
+ return EOF;
1569
+ }
1570
+ eatBits(1);
1571
+ code1 = lookBits(13);
1572
+ } while ((code1 >> 1) != 0x001);
1573
+ eatBits(12);
1574
+ if (encoding > 0) {
1575
+ eatBits(1);
1576
+ nextLine2D = !(code1 & 1);
1577
+ }
1578
+ }
1579
+
1580
+ a0 = 0;
1581
+ outputBits = codingLine[1] - codingLine[0];
1582
+ if (outputBits == 0) {
1583
+ a0 = 1;
1584
+ outputBits = codingLine[2] - codingLine[1];
1585
+ }
1586
+
1587
+ ++row;
1588
+ }
1589
+
1590
+ // get a byte
1591
+ if (outputBits >= 8) {
1592
+ ret = ((a0 & 1) == 0) ? 0xff : 0x00;
1593
+ if ((outputBits -= 8) == 0) {
1594
+ ++a0;
1595
+ if (codingLine[a0] < columns) {
1596
+ outputBits = codingLine[a0 + 1] - codingLine[a0];
1597
+ }
1598
+ }
1599
+ } else {
1600
+ bits = 8;
1601
+ ret = 0;
1602
+ do {
1603
+ if (outputBits > bits) {
1604
+ i = bits;
1605
+ bits = 0;
1606
+ if ((a0 & 1) == 0) {
1607
+ ret |= 0xff >> (8 - i);
1608
+ }
1609
+ outputBits -= i;
1610
+ } else {
1611
+ i = outputBits;
1612
+ bits -= outputBits;
1613
+ if ((a0 & 1) == 0) {
1614
+ ret |= (0xff >> (8 - i)) << bits;
1615
+ }
1616
+ outputBits = 0;
1617
+ ++a0;
1618
+ if (codingLine[a0] < columns) {
1619
+ outputBits = codingLine[a0 + 1] - codingLine[a0];
1620
+ }
1621
+ }
1622
+ } while (bits > 0 && codingLine[a0] < columns);
1623
+ }
1624
+ buf = black ? (ret ^ 0xff) : ret;
1625
+ return buf;
1626
+ }
1627
+
1628
+ short CCITTFaxStream::getTwoDimCode() {
1629
+ short code;
1630
+ CCITTCode *p;
1631
+ int n;
1632
+
1633
+ code = 0; // make gcc happy
1634
+ if (endOfBlock) {
1635
+ code = lookBits(7);
1636
+ p = &twoDimTab1[code];
1637
+ if (p->bits > 0) {
1638
+ eatBits(p->bits);
1639
+ return p->n;
1640
+ }
1641
+ } else {
1642
+ for (n = 1; n <= 7; ++n) {
1643
+ code = lookBits(n);
1644
+ if (n < 7) {
1645
+ code <<= 7 - n;
1646
+ }
1647
+ p = &twoDimTab1[code];
1648
+ if (p->bits == n) {
1649
+ eatBits(n);
1650
+ return p->n;
1651
+ }
1652
+ }
1653
+ }
1654
+ error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
1655
+ return EOF;
1656
+ }
1657
+
1658
+ short CCITTFaxStream::getWhiteCode() {
1659
+ short code;
1660
+ CCITTCode *p;
1661
+ int n;
1662
+
1663
+ code = 0; // make gcc happy
1664
+ if (endOfBlock) {
1665
+ code = lookBits(12);
1666
+ if ((code >> 5) == 0) {
1667
+ p = &whiteTab1[code];
1668
+ } else {
1669
+ p = &whiteTab2[code >> 3];
1670
+ }
1671
+ if (p->bits > 0) {
1672
+ eatBits(p->bits);
1673
+ return p->n;
1674
+ }
1675
+ } else {
1676
+ for (n = 1; n <= 9; ++n) {
1677
+ code = lookBits(n);
1678
+ if (n < 9) {
1679
+ code <<= 9 - n;
1680
+ }
1681
+ p = &whiteTab2[code];
1682
+ if (p->bits == n) {
1683
+ eatBits(n);
1684
+ return p->n;
1685
+ }
1686
+ }
1687
+ for (n = 11; n <= 12; ++n) {
1688
+ code = lookBits(n);
1689
+ if (n < 12) {
1690
+ code <<= 12 - n;
1691
+ }
1692
+ p = &whiteTab1[code];
1693
+ if (p->bits == n) {
1694
+ eatBits(n);
1695
+ return p->n;
1696
+ }
1697
+ }
1698
+ }
1699
+ error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
1700
+ // eat a bit and return a positive number so that the caller doesn't
1701
+ // go into an infinite loop
1702
+ eatBits(1);
1703
+ return 1;
1704
+ }
1705
+
1706
+ short CCITTFaxStream::getBlackCode() {
1707
+ short code;
1708
+ CCITTCode *p;
1709
+ int n;
1710
+
1711
+ code = 0; // make gcc happy
1712
+ if (endOfBlock) {
1713
+ code = lookBits(13);
1714
+ if ((code >> 7) == 0) {
1715
+ p = &blackTab1[code];
1716
+ } else if ((code >> 9) == 0) {
1717
+ p = &blackTab2[(code >> 1) - 64];
1718
+ } else {
1719
+ p = &blackTab3[code >> 7];
1720
+ }
1721
+ if (p->bits > 0) {
1722
+ eatBits(p->bits);
1723
+ return p->n;
1724
+ }
1725
+ } else {
1726
+ for (n = 2; n <= 6; ++n) {
1727
+ code = lookBits(n);
1728
+ if (n < 6) {
1729
+ code <<= 6 - n;
1730
+ }
1731
+ p = &blackTab3[code];
1732
+ if (p->bits == n) {
1733
+ eatBits(n);
1734
+ return p->n;
1735
+ }
1736
+ }
1737
+ for (n = 7; n <= 12; ++n) {
1738
+ code = lookBits(n);
1739
+ if (n < 12) {
1740
+ code <<= 12 - n;
1741
+ }
1742
+ if (code >= 64) {
1743
+ p = &blackTab2[code - 64];
1744
+ if (p->bits == n) {
1745
+ eatBits(n);
1746
+ return p->n;
1747
+ }
1748
+ }
1749
+ }
1750
+ for (n = 10; n <= 13; ++n) {
1751
+ code = lookBits(n);
1752
+ if (n < 13) {
1753
+ code <<= 13 - n;
1754
+ }
1755
+ p = &blackTab1[code];
1756
+ if (p->bits == n) {
1757
+ eatBits(n);
1758
+ return p->n;
1759
+ }
1760
+ }
1761
+ }
1762
+ error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
1763
+ // eat a bit and return a positive number so that the caller doesn't
1764
+ // go into an infinite loop
1765
+ eatBits(1);
1766
+ return 1;
1767
+ }
1768
+
1769
+ short CCITTFaxStream::lookBits(int n) {
1770
+ int c;
1771
+
1772
+ while (inputBits < n) {
1773
+ if ((c = str->getChar()) == EOF) {
1774
+ if (inputBits == 0) {
1775
+ return EOF;
1776
+ }
1777
+ // near the end of the stream, the caller may ask for more bits
1778
+ // than are available, but there may still be a valid code in
1779
+ // however many bits are available -- we need to return correct
1780
+ // data in this case
1781
+ return (inputBuf << (n - inputBits)) & (0xffff >> (16 - n));
1782
+ }
1783
+ inputBuf = (inputBuf << 8) + c;
1784
+ inputBits += 8;
1785
+ }
1786
+ return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
1787
+ }
1788
+
1789
+ GString *CCITTFaxStream::getPSFilter(int psLevel, char *indent) {
1790
+ GString *s;
1791
+ char s1[50];
1792
+
1793
+ if (psLevel < 2) {
1794
+ return NULL;
1795
+ }
1796
+ if (!(s = str->getPSFilter(psLevel, indent))) {
1797
+ return NULL;
1798
+ }
1799
+ s->append(indent)->append("<< ");
1800
+ if (encoding != 0) {
1801
+ sprintf(s1, "/K %d ", encoding);
1802
+ s->append(s1);
1803
+ }
1804
+ if (endOfLine) {
1805
+ s->append("/EndOfLine true ");
1806
+ }
1807
+ if (byteAlign) {
1808
+ s->append("/EncodedByteAlign true ");
1809
+ }
1810
+ sprintf(s1, "/Columns %d ", columns);
1811
+ s->append(s1);
1812
+ if (rows != 0) {
1813
+ sprintf(s1, "/Rows %d ", rows);
1814
+ s->append(s1);
1815
+ }
1816
+ if (!endOfBlock) {
1817
+ s->append("/EndOfBlock false ");
1818
+ }
1819
+ if (black) {
1820
+ s->append("/BlackIs1 true ");
1821
+ }
1822
+ s->append(">> /CCITTFaxDecode filter\n");
1823
+ return s;
1824
+ }
1825
+
1826
+ GBool CCITTFaxStream::isBinary(GBool last) {
1827
+ return str->isBinary(gTrue);
1828
+ }
1829
+
1830
+ //------------------------------------------------------------------------
1831
+ // DCTStream
1832
+ //------------------------------------------------------------------------
1833
+
1834
+ // IDCT constants (20.12 fixed point format)
1835
+ #define dctCos1 4017 // cos(pi/16)
1836
+ #define dctSin1 799 // sin(pi/16)
1837
+ #define dctCos3 3406 // cos(3*pi/16)
1838
+ #define dctSin3 2276 // sin(3*pi/16)
1839
+ #define dctCos6 1567 // cos(6*pi/16)
1840
+ #define dctSin6 3784 // sin(6*pi/16)
1841
+ #define dctSqrt2 5793 // sqrt(2)
1842
+ #define dctSqrt1d2 2896 // sqrt(2) / 2
1843
+
1844
+ // color conversion parameters (16.16 fixed point format)
1845
+ #define dctCrToR 91881 // 1.4020
1846
+ #define dctCbToG -22553 // -0.3441363
1847
+ #define dctCrToG -46802 // -0.71413636
1848
+ #define dctCbToB 116130 // 1.772
1849
+
1850
+ // clip [-256,511] --> [0,255]
1851
+ #define dctClipOffset 256
1852
+ static Guchar dctClip[768];
1853
+ static int dctClipInit = 0;
1854
+
1855
+ // zig zag decode map
1856
+ static int dctZigZag[64] = {
1857
+ 0,
1858
+ 1, 8,
1859
+ 16, 9, 2,
1860
+ 3, 10, 17, 24,
1861
+ 32, 25, 18, 11, 4,
1862
+ 5, 12, 19, 26, 33, 40,
1863
+ 48, 41, 34, 27, 20, 13, 6,
1864
+ 7, 14, 21, 28, 35, 42, 49, 56,
1865
+ 57, 50, 43, 36, 29, 22, 15,
1866
+ 23, 30, 37, 44, 51, 58,
1867
+ 59, 52, 45, 38, 31,
1868
+ 39, 46, 53, 60,
1869
+ 61, 54, 47,
1870
+ 55, 62,
1871
+ 63
1872
+ };
1873
+
1874
+ DCTStream::DCTStream(Stream *strA, GBool colorXformA):
1875
+ FilterStream(strA) {
1876
+ int i, j;
1877
+
1878
+ colorXform = colorXformA;
1879
+ progressive = interleaved = gFalse;
1880
+ width = height = 0;
1881
+ mcuWidth = mcuHeight = 0;
1882
+ numComps = 0;
1883
+ comp = 0;
1884
+ x = y = dy = 0;
1885
+ for (i = 0; i < 4; ++i) {
1886
+ for (j = 0; j < 32; ++j) {
1887
+ rowBuf[i][j] = NULL;
1888
+ }
1889
+ frameBuf[i] = NULL;
1890
+ }
1891
+
1892
+ if (!dctClipInit) {
1893
+ for (i = -256; i < 0; ++i)
1894
+ dctClip[dctClipOffset + i] = 0;
1895
+ for (i = 0; i < 256; ++i)
1896
+ dctClip[dctClipOffset + i] = i;
1897
+ for (i = 256; i < 512; ++i)
1898
+ dctClip[dctClipOffset + i] = 255;
1899
+ dctClipInit = 1;
1900
+ }
1901
+ }
1902
+
1903
+ DCTStream::~DCTStream() {
1904
+ close();
1905
+ delete str;
1906
+ }
1907
+
1908
+ void DCTStream::reset() {
1909
+ int i, j;
1910
+
1911
+ str->reset();
1912
+
1913
+ progressive = interleaved = gFalse;
1914
+ width = height = 0;
1915
+ numComps = 0;
1916
+ numQuantTables = 0;
1917
+ numDCHuffTables = 0;
1918
+ numACHuffTables = 0;
1919
+ gotJFIFMarker = gFalse;
1920
+ gotAdobeMarker = gFalse;
1921
+ restartInterval = 0;
1922
+
1923
+ if (!readHeader()) {
1924
+ y = height;
1925
+ return;
1926
+ }
1927
+
1928
+ // compute MCU size
1929
+ if (numComps == 1) {
1930
+ compInfo[0].hSample = compInfo[0].vSample = 1;
1931
+ }
1932
+ mcuWidth = compInfo[0].hSample;
1933
+ mcuHeight = compInfo[0].vSample;
1934
+ for (i = 1; i < numComps; ++i) {
1935
+ if (compInfo[i].hSample > mcuWidth) {
1936
+ mcuWidth = compInfo[i].hSample;
1937
+ }
1938
+ if (compInfo[i].vSample > mcuHeight) {
1939
+ mcuHeight = compInfo[i].vSample;
1940
+ }
1941
+ }
1942
+ mcuWidth *= 8;
1943
+ mcuHeight *= 8;
1944
+
1945
+ // figure out color transform
1946
+ if (colorXform == -1) {
1947
+ if (numComps == 3) {
1948
+ if (gotJFIFMarker) {
1949
+ colorXform = 1;
1950
+ } else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
1951
+ compInfo[2].id == 66) { // ASCII "RGB"
1952
+ colorXform = 0;
1953
+ } else {
1954
+ colorXform = 1;
1955
+ }
1956
+ } else {
1957
+ colorXform = 0;
1958
+ }
1959
+ }
1960
+
1961
+ if (progressive || !interleaved) {
1962
+
1963
+ // allocate a buffer for the whole image
1964
+ bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
1965
+ bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
1966
+ for (i = 0; i < numComps; ++i) {
1967
+ frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
1968
+ memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
1969
+ }
1970
+
1971
+ // read the image data
1972
+ do {
1973
+ restartMarker = 0xd0;
1974
+ restart();
1975
+ readScan();
1976
+ } while (readHeader());
1977
+
1978
+ // decode
1979
+ decodeImage();
1980
+
1981
+ // initialize counters
1982
+ comp = 0;
1983
+ x = 0;
1984
+ y = 0;
1985
+
1986
+ } else {
1987
+
1988
+ // allocate a buffer for one row of MCUs
1989
+ bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
1990
+ for (i = 0; i < numComps; ++i) {
1991
+ for (j = 0; j < mcuHeight; ++j) {
1992
+ rowBuf[i][j] = (Guchar *)gmallocn(bufWidth, sizeof(Guchar));
1993
+ }
1994
+ }
1995
+
1996
+ // initialize counters
1997
+ comp = 0;
1998
+ x = 0;
1999
+ y = 0;
2000
+ dy = mcuHeight;
2001
+
2002
+ restartMarker = 0xd0;
2003
+ restart();
2004
+ }
2005
+ }
2006
+
2007
+ void DCTStream::close() {
2008
+ int i, j;
2009
+
2010
+ for (i = 0; i < 4; ++i) {
2011
+ for (j = 0; j < 32; ++j) {
2012
+ gfree(rowBuf[i][j]);
2013
+ rowBuf[i][j] = NULL;
2014
+ }
2015
+ gfree(frameBuf[i]);
2016
+ frameBuf[i] = NULL;
2017
+ }
2018
+ FilterStream::close();
2019
+ }
2020
+
2021
+ int DCTStream::getChar() {
2022
+ int c;
2023
+
2024
+ if (y >= height) {
2025
+ return EOF;
2026
+ }
2027
+ if (progressive || !interleaved) {
2028
+ c = frameBuf[comp][y * bufWidth + x];
2029
+ if (++comp == numComps) {
2030
+ comp = 0;
2031
+ if (++x == width) {
2032
+ x = 0;
2033
+ ++y;
2034
+ }
2035
+ }
2036
+ } else {
2037
+ if (dy >= mcuHeight) {
2038
+ if (!readMCURow()) {
2039
+ y = height;
2040
+ return EOF;
2041
+ }
2042
+ comp = 0;
2043
+ x = 0;
2044
+ dy = 0;
2045
+ }
2046
+ c = rowBuf[comp][dy][x];
2047
+ if (++comp == numComps) {
2048
+ comp = 0;
2049
+ if (++x == width) {
2050
+ x = 0;
2051
+ ++y;
2052
+ ++dy;
2053
+ if (y == height) {
2054
+ readTrailer();
2055
+ }
2056
+ }
2057
+ }
2058
+ }
2059
+ return c;
2060
+ }
2061
+
2062
+ int DCTStream::lookChar() {
2063
+ if (y >= height) {
2064
+ return EOF;
2065
+ }
2066
+ if (progressive || !interleaved) {
2067
+ return frameBuf[comp][y * bufWidth + x];
2068
+ } else {
2069
+ if (dy >= mcuHeight) {
2070
+ if (!readMCURow()) {
2071
+ y = height;
2072
+ return EOF;
2073
+ }
2074
+ comp = 0;
2075
+ x = 0;
2076
+ dy = 0;
2077
+ }
2078
+ return rowBuf[comp][dy][x];
2079
+ }
2080
+ }
2081
+
2082
+ void DCTStream::restart() {
2083
+ int i;
2084
+
2085
+ inputBits = 0;
2086
+ restartCtr = restartInterval;
2087
+ for (i = 0; i < numComps; ++i) {
2088
+ compInfo[i].prevDC = 0;
2089
+ }
2090
+ eobRun = 0;
2091
+ }
2092
+
2093
+ // Read one row of MCUs from a sequential JPEG stream.
2094
+ GBool DCTStream::readMCURow() {
2095
+ int data1[64];
2096
+ Guchar data2[64];
2097
+ Guchar *p1, *p2;
2098
+ int pY, pCb, pCr, pR, pG, pB;
2099
+ int h, v, horiz, vert, hSub, vSub;
2100
+ int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2101
+ int c;
2102
+
2103
+ for (x1 = 0; x1 < width; x1 += mcuWidth) {
2104
+
2105
+ // deal with restart marker
2106
+ if (restartInterval > 0 && restartCtr == 0) {
2107
+ c = readMarker();
2108
+ if (c != restartMarker) {
2109
+ error(getPos(), "Bad DCT data: incorrect restart marker");
2110
+ return gFalse;
2111
+ }
2112
+ if (++restartMarker == 0xd8)
2113
+ restartMarker = 0xd0;
2114
+ restart();
2115
+ }
2116
+
2117
+ // read one MCU
2118
+ for (cc = 0; cc < numComps; ++cc) {
2119
+ h = compInfo[cc].hSample;
2120
+ v = compInfo[cc].vSample;
2121
+ horiz = mcuWidth / h;
2122
+ vert = mcuHeight / v;
2123
+ hSub = horiz / 8;
2124
+ vSub = vert / 8;
2125
+ for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2126
+ for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2127
+ if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
2128
+ &acHuffTables[scanInfo.acHuffTable[cc]],
2129
+ &compInfo[cc].prevDC,
2130
+ data1)) {
2131
+ return gFalse;
2132
+ }
2133
+ transformDataUnit(quantTables[compInfo[cc].quantTable],
2134
+ data1, data2);
2135
+ if (hSub == 1 && vSub == 1) {
2136
+ for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2137
+ p1 = &rowBuf[cc][y2+y3][x1+x2];
2138
+ p1[0] = data2[i];
2139
+ p1[1] = data2[i+1];
2140
+ p1[2] = data2[i+2];
2141
+ p1[3] = data2[i+3];
2142
+ p1[4] = data2[i+4];
2143
+ p1[5] = data2[i+5];
2144
+ p1[6] = data2[i+6];
2145
+ p1[7] = data2[i+7];
2146
+ }
2147
+ } else if (hSub == 2 && vSub == 2) {
2148
+ for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2149
+ p1 = &rowBuf[cc][y2+y3][x1+x2];
2150
+ p2 = &rowBuf[cc][y2+y3+1][x1+x2];
2151
+ p1[0] = p1[1] = p2[0] = p2[1] = data2[i];
2152
+ p1[2] = p1[3] = p2[2] = p2[3] = data2[i+1];
2153
+ p1[4] = p1[5] = p2[4] = p2[5] = data2[i+2];
2154
+ p1[6] = p1[7] = p2[6] = p2[7] = data2[i+3];
2155
+ p1[8] = p1[9] = p2[8] = p2[9] = data2[i+4];
2156
+ p1[10] = p1[11] = p2[10] = p2[11] = data2[i+5];
2157
+ p1[12] = p1[13] = p2[12] = p2[13] = data2[i+6];
2158
+ p1[14] = p1[15] = p2[14] = p2[15] = data2[i+7];
2159
+ }
2160
+ } else {
2161
+ i = 0;
2162
+ for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2163
+ for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2164
+ for (y5 = 0; y5 < vSub; ++y5)
2165
+ for (x5 = 0; x5 < hSub; ++x5)
2166
+ rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data2[i];
2167
+ ++i;
2168
+ }
2169
+ }
2170
+ }
2171
+ }
2172
+ }
2173
+ }
2174
+ --restartCtr;
2175
+
2176
+ // color space conversion
2177
+ if (colorXform) {
2178
+ // convert YCbCr to RGB
2179
+ if (numComps == 3) {
2180
+ for (y2 = 0; y2 < mcuHeight; ++y2) {
2181
+ for (x2 = 0; x2 < mcuWidth; ++x2) {
2182
+ pY = rowBuf[0][y2][x1+x2];
2183
+ pCb = rowBuf[1][y2][x1+x2] - 128;
2184
+ pCr = rowBuf[2][y2][x1+x2] - 128;
2185
+ pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2186
+ rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
2187
+ pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2188
+ rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
2189
+ pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2190
+ rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
2191
+ }
2192
+ }
2193
+ // convert YCbCrK to CMYK (K is passed through unchanged)
2194
+ } else if (numComps == 4) {
2195
+ for (y2 = 0; y2 < mcuHeight; ++y2) {
2196
+ for (x2 = 0; x2 < mcuWidth; ++x2) {
2197
+ pY = rowBuf[0][y2][x1+x2];
2198
+ pCb = rowBuf[1][y2][x1+x2] - 128;
2199
+ pCr = rowBuf[2][y2][x1+x2] - 128;
2200
+ pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2201
+ rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
2202
+ pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2203
+ rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
2204
+ pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2205
+ rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
2206
+ }
2207
+ }
2208
+ }
2209
+ }
2210
+ }
2211
+ return gTrue;
2212
+ }
2213
+
2214
+ // Read one scan from a progressive or non-interleaved JPEG stream.
2215
+ void DCTStream::readScan() {
2216
+ int data[64];
2217
+ int x1, y1, dx1, dy1, x2, y2, y3, cc, i;
2218
+ int h, v, horiz, vert, vSub;
2219
+ int *p1;
2220
+ int c;
2221
+
2222
+ if (scanInfo.numComps == 1) {
2223
+ for (cc = 0; cc < numComps; ++cc) {
2224
+ if (scanInfo.comp[cc]) {
2225
+ break;
2226
+ }
2227
+ }
2228
+ dx1 = mcuWidth / compInfo[cc].hSample;
2229
+ dy1 = mcuHeight / compInfo[cc].vSample;
2230
+ } else {
2231
+ dx1 = mcuWidth;
2232
+ dy1 = mcuHeight;
2233
+ }
2234
+
2235
+ for (y1 = 0; y1 < height; y1 += dy1) {
2236
+ for (x1 = 0; x1 < width; x1 += dx1) {
2237
+
2238
+ // deal with restart marker
2239
+ if (restartInterval > 0 && restartCtr == 0) {
2240
+ c = readMarker();
2241
+ if (c != restartMarker) {
2242
+ error(getPos(), "Bad DCT data: incorrect restart marker");
2243
+ return;
2244
+ }
2245
+ if (++restartMarker == 0xd8) {
2246
+ restartMarker = 0xd0;
2247
+ }
2248
+ restart();
2249
+ }
2250
+
2251
+ // read one MCU
2252
+ for (cc = 0; cc < numComps; ++cc) {
2253
+ if (!scanInfo.comp[cc]) {
2254
+ continue;
2255
+ }
2256
+
2257
+ h = compInfo[cc].hSample;
2258
+ v = compInfo[cc].vSample;
2259
+ horiz = mcuWidth / h;
2260
+ vert = mcuHeight / v;
2261
+ vSub = vert / 8;
2262
+ for (y2 = 0; y2 < dy1; y2 += vert) {
2263
+ for (x2 = 0; x2 < dx1; x2 += horiz) {
2264
+
2265
+ // pull out the current values
2266
+ p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2267
+ for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2268
+ data[i] = p1[0];
2269
+ data[i+1] = p1[1];
2270
+ data[i+2] = p1[2];
2271
+ data[i+3] = p1[3];
2272
+ data[i+4] = p1[4];
2273
+ data[i+5] = p1[5];
2274
+ data[i+6] = p1[6];
2275
+ data[i+7] = p1[7];
2276
+ p1 += bufWidth * vSub;
2277
+ }
2278
+
2279
+ // read one data unit
2280
+ if (progressive) {
2281
+ if (!readProgressiveDataUnit(
2282
+ &dcHuffTables[scanInfo.dcHuffTable[cc]],
2283
+ &acHuffTables[scanInfo.acHuffTable[cc]],
2284
+ &compInfo[cc].prevDC,
2285
+ data)) {
2286
+ return;
2287
+ }
2288
+ } else {
2289
+ if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
2290
+ &acHuffTables[scanInfo.acHuffTable[cc]],
2291
+ &compInfo[cc].prevDC,
2292
+ data)) {
2293
+ return;
2294
+ }
2295
+ }
2296
+
2297
+ // add the data unit into frameBuf
2298
+ p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2299
+ for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2300
+ p1[0] = data[i];
2301
+ p1[1] = data[i+1];
2302
+ p1[2] = data[i+2];
2303
+ p1[3] = data[i+3];
2304
+ p1[4] = data[i+4];
2305
+ p1[5] = data[i+5];
2306
+ p1[6] = data[i+6];
2307
+ p1[7] = data[i+7];
2308
+ p1 += bufWidth * vSub;
2309
+ }
2310
+ }
2311
+ }
2312
+ }
2313
+ --restartCtr;
2314
+ }
2315
+ }
2316
+ }
2317
+
2318
+ // Read one data unit from a sequential JPEG stream.
2319
+ GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2320
+ DCTHuffTable *acHuffTable,
2321
+ int *prevDC, int data[64]) {
2322
+ int run, size, amp;
2323
+ int c;
2324
+ int i, j;
2325
+
2326
+ if ((size = readHuffSym(dcHuffTable)) == 9999) {
2327
+ return gFalse;
2328
+ }
2329
+ if (size > 0) {
2330
+ if ((amp = readAmp(size)) == 9999) {
2331
+ return gFalse;
2332
+ }
2333
+ } else {
2334
+ amp = 0;
2335
+ }
2336
+ data[0] = *prevDC += amp;
2337
+ for (i = 1; i < 64; ++i) {
2338
+ data[i] = 0;
2339
+ }
2340
+ i = 1;
2341
+ while (i < 64) {
2342
+ run = 0;
2343
+ while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
2344
+ run += 0x10;
2345
+ }
2346
+ if (c == 9999) {
2347
+ return gFalse;
2348
+ }
2349
+ if (c == 0x00) {
2350
+ break;
2351
+ } else {
2352
+ run += (c >> 4) & 0x0f;
2353
+ size = c & 0x0f;
2354
+ amp = readAmp(size);
2355
+ if (amp == 9999) {
2356
+ return gFalse;
2357
+ }
2358
+ i += run;
2359
+ if (i < 64) {
2360
+ j = dctZigZag[i++];
2361
+ data[j] = amp;
2362
+ }
2363
+ }
2364
+ }
2365
+ return gTrue;
2366
+ }
2367
+
2368
+ // Read one data unit from a sequential JPEG stream.
2369
+ GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
2370
+ DCTHuffTable *acHuffTable,
2371
+ int *prevDC, int data[64]) {
2372
+ int run, size, amp, bit, c;
2373
+ int i, j, k;
2374
+
2375
+ // get the DC coefficient
2376
+ i = scanInfo.firstCoeff;
2377
+ if (i == 0) {
2378
+ if (scanInfo.ah == 0) {
2379
+ if ((size = readHuffSym(dcHuffTable)) == 9999) {
2380
+ return gFalse;
2381
+ }
2382
+ if (size > 0) {
2383
+ if ((amp = readAmp(size)) == 9999) {
2384
+ return gFalse;
2385
+ }
2386
+ } else {
2387
+ amp = 0;
2388
+ }
2389
+ data[0] += (*prevDC += amp) << scanInfo.al;
2390
+ } else {
2391
+ if ((bit = readBit()) == 9999) {
2392
+ return gFalse;
2393
+ }
2394
+ data[0] += bit << scanInfo.al;
2395
+ }
2396
+ ++i;
2397
+ }
2398
+ if (scanInfo.lastCoeff == 0) {
2399
+ return gTrue;
2400
+ }
2401
+
2402
+ // check for an EOB run
2403
+ if (eobRun > 0) {
2404
+ while (i <= scanInfo.lastCoeff) {
2405
+ j = dctZigZag[i++];
2406
+ if (data[j] != 0) {
2407
+ if ((bit = readBit()) == EOF) {
2408
+ return gFalse;
2409
+ }
2410
+ if (bit) {
2411
+ data[j] += 1 << scanInfo.al;
2412
+ }
2413
+ }
2414
+ }
2415
+ --eobRun;
2416
+ return gTrue;
2417
+ }
2418
+
2419
+ // read the AC coefficients
2420
+ while (i <= scanInfo.lastCoeff) {
2421
+ if ((c = readHuffSym(acHuffTable)) == 9999) {
2422
+ return gFalse;
2423
+ }
2424
+
2425
+ // ZRL
2426
+ if (c == 0xf0) {
2427
+ k = 0;
2428
+ while (k < 16) {
2429
+ j = dctZigZag[i++];
2430
+ if (data[j] == 0) {
2431
+ ++k;
2432
+ } else {
2433
+ if ((bit = readBit()) == EOF) {
2434
+ return gFalse;
2435
+ }
2436
+ if (bit) {
2437
+ data[j] += 1 << scanInfo.al;
2438
+ }
2439
+ }
2440
+ }
2441
+
2442
+ // EOB run
2443
+ } else if ((c & 0x0f) == 0x00) {
2444
+ j = c >> 4;
2445
+ eobRun = 0;
2446
+ for (k = 0; k < j; ++k) {
2447
+ if ((bit = readBit()) == EOF) {
2448
+ return gFalse;
2449
+ }
2450
+ eobRun = (eobRun << 1) | bit;
2451
+ }
2452
+ eobRun += 1 << j;
2453
+ while (i <= scanInfo.lastCoeff) {
2454
+ j = dctZigZag[i++];
2455
+ if (data[j] != 0) {
2456
+ if ((bit = readBit()) == EOF) {
2457
+ return gFalse;
2458
+ }
2459
+ if (bit) {
2460
+ data[j] += 1 << scanInfo.al;
2461
+ }
2462
+ }
2463
+ }
2464
+ --eobRun;
2465
+ break;
2466
+
2467
+ // zero run and one AC coefficient
2468
+ } else {
2469
+ run = (c >> 4) & 0x0f;
2470
+ size = c & 0x0f;
2471
+ if ((amp = readAmp(size)) == 9999) {
2472
+ return gFalse;
2473
+ }
2474
+ k = 0;
2475
+ do {
2476
+ j = dctZigZag[i++];
2477
+ while (data[j] != 0) {
2478
+ if ((bit = readBit()) == EOF) {
2479
+ return gFalse;
2480
+ }
2481
+ if (bit) {
2482
+ data[j] += 1 << scanInfo.al;
2483
+ }
2484
+ j = dctZigZag[i++];
2485
+ }
2486
+ ++k;
2487
+ } while (k <= run);
2488
+ data[j] = amp << scanInfo.al;
2489
+ }
2490
+ }
2491
+
2492
+ return gTrue;
2493
+ }
2494
+
2495
+ // Decode a progressive JPEG image.
2496
+ void DCTStream::decodeImage() {
2497
+ int dataIn[64];
2498
+ Guchar dataOut[64];
2499
+ Gushort *quantTable;
2500
+ int pY, pCb, pCr, pR, pG, pB;
2501
+ int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2502
+ int h, v, horiz, vert, hSub, vSub;
2503
+ int *p0, *p1, *p2;
2504
+
2505
+ for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
2506
+ for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
2507
+ for (cc = 0; cc < numComps; ++cc) {
2508
+ quantTable = quantTables[compInfo[cc].quantTable];
2509
+ h = compInfo[cc].hSample;
2510
+ v = compInfo[cc].vSample;
2511
+ horiz = mcuWidth / h;
2512
+ vert = mcuHeight / v;
2513
+ hSub = horiz / 8;
2514
+ vSub = vert / 8;
2515
+ for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2516
+ for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2517
+
2518
+ // pull out the coded data unit
2519
+ p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2520
+ for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2521
+ dataIn[i] = p1[0];
2522
+ dataIn[i+1] = p1[1];
2523
+ dataIn[i+2] = p1[2];
2524
+ dataIn[i+3] = p1[3];
2525
+ dataIn[i+4] = p1[4];
2526
+ dataIn[i+5] = p1[5];
2527
+ dataIn[i+6] = p1[6];
2528
+ dataIn[i+7] = p1[7];
2529
+ p1 += bufWidth * vSub;
2530
+ }
2531
+
2532
+ // transform
2533
+ transformDataUnit(quantTable, dataIn, dataOut);
2534
+
2535
+ // store back into frameBuf, doing replication for
2536
+ // subsampled components
2537
+ p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2538
+ if (hSub == 1 && vSub == 1) {
2539
+ for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2540
+ p1[0] = dataOut[i] & 0xff;
2541
+ p1[1] = dataOut[i+1] & 0xff;
2542
+ p1[2] = dataOut[i+2] & 0xff;
2543
+ p1[3] = dataOut[i+3] & 0xff;
2544
+ p1[4] = dataOut[i+4] & 0xff;
2545
+ p1[5] = dataOut[i+5] & 0xff;
2546
+ p1[6] = dataOut[i+6] & 0xff;
2547
+ p1[7] = dataOut[i+7] & 0xff;
2548
+ p1 += bufWidth;
2549
+ }
2550
+ } else if (hSub == 2 && vSub == 2) {
2551
+ p2 = p1 + bufWidth;
2552
+ for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2553
+ p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
2554
+ p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff;
2555
+ p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff;
2556
+ p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff;
2557
+ p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff;
2558
+ p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff;
2559
+ p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff;
2560
+ p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff;
2561
+ p1 += bufWidth * 2;
2562
+ p2 += bufWidth * 2;
2563
+ }
2564
+ } else {
2565
+ i = 0;
2566
+ for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2567
+ for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2568
+ p2 = p1 + x4;
2569
+ for (y5 = 0; y5 < vSub; ++y5) {
2570
+ for (x5 = 0; x5 < hSub; ++x5) {
2571
+ p2[x5] = dataOut[i] & 0xff;
2572
+ }
2573
+ p2 += bufWidth;
2574
+ }
2575
+ ++i;
2576
+ }
2577
+ p1 += bufWidth * vSub;
2578
+ }
2579
+ }
2580
+ }
2581
+ }
2582
+ }
2583
+
2584
+ // color space conversion
2585
+ if (colorXform) {
2586
+ // convert YCbCr to RGB
2587
+ if (numComps == 3) {
2588
+ for (y2 = 0; y2 < mcuHeight; ++y2) {
2589
+ p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
2590
+ p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
2591
+ p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
2592
+ for (x2 = 0; x2 < mcuWidth; ++x2) {
2593
+ pY = *p0;
2594
+ pCb = *p1 - 128;
2595
+ pCr = *p2 - 128;
2596
+ pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2597
+ *p0++ = dctClip[dctClipOffset + pR];
2598
+ pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
2599
+ 32768) >> 16;
2600
+ *p1++ = dctClip[dctClipOffset + pG];
2601
+ pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2602
+ *p2++ = dctClip[dctClipOffset + pB];
2603
+ }
2604
+ }
2605
+ // convert YCbCrK to CMYK (K is passed through unchanged)
2606
+ } else if (numComps == 4) {
2607
+ for (y2 = 0; y2 < mcuHeight; ++y2) {
2608
+ p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
2609
+ p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
2610
+ p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
2611
+ for (x2 = 0; x2 < mcuWidth; ++x2) {
2612
+ pY = *p0;
2613
+ pCb = *p1 - 128;
2614
+ pCr = *p2 - 128;
2615
+ pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2616
+ *p0++ = 255 - dctClip[dctClipOffset + pR];
2617
+ pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
2618
+ 32768) >> 16;
2619
+ *p1++ = 255 - dctClip[dctClipOffset + pG];
2620
+ pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2621
+ *p2++ = 255 - dctClip[dctClipOffset + pB];
2622
+ }
2623
+ }
2624
+ }
2625
+ }
2626
+ }
2627
+ }
2628
+ }
2629
+
2630
+ // Transform one data unit -- this performs the dequantization and
2631
+ // IDCT steps. This IDCT algorithm is taken from:
2632
+ // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
2633
+ // "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
2634
+ // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
2635
+ // 988-991.
2636
+ // The stage numbers mentioned in the comments refer to Figure 1 in this
2637
+ // paper.
2638
+ void DCTStream::transformDataUnit(Gushort *quantTable,
2639
+ int dataIn[64], Guchar dataOut[64]) {
2640
+ int v0, v1, v2, v3, v4, v5, v6, v7, t;
2641
+ int *p;
2642
+ int i;
2643
+
2644
+ // dequant
2645
+ for (i = 0; i < 64; ++i) {
2646
+ dataIn[i] *= quantTable[i];
2647
+ }
2648
+
2649
+ // inverse DCT on rows
2650
+ for (i = 0; i < 64; i += 8) {
2651
+ p = dataIn + i;
2652
+
2653
+ // check for all-zero AC coefficients
2654
+ if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
2655
+ p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
2656
+ t = (dctSqrt2 * p[0] + 512) >> 10;
2657
+ p[0] = t;
2658
+ p[1] = t;
2659
+ p[2] = t;
2660
+ p[3] = t;
2661
+ p[4] = t;
2662
+ p[5] = t;
2663
+ p[6] = t;
2664
+ p[7] = t;
2665
+ continue;
2666
+ }
2667
+
2668
+ // stage 4
2669
+ v0 = (dctSqrt2 * p[0] + 128) >> 8;
2670
+ v1 = (dctSqrt2 * p[4] + 128) >> 8;
2671
+ v2 = p[2];
2672
+ v3 = p[6];
2673
+ v4 = (dctSqrt1d2 * (p[1] - p[7]) + 128) >> 8;
2674
+ v7 = (dctSqrt1d2 * (p[1] + p[7]) + 128) >> 8;
2675
+ v5 = p[3] << 4;
2676
+ v6 = p[5] << 4;
2677
+
2678
+ // stage 3
2679
+ t = (v0 - v1+ 1) >> 1;
2680
+ v0 = (v0 + v1 + 1) >> 1;
2681
+ v1 = t;
2682
+ t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
2683
+ v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
2684
+ v3 = t;
2685
+ t = (v4 - v6 + 1) >> 1;
2686
+ v4 = (v4 + v6 + 1) >> 1;
2687
+ v6 = t;
2688
+ t = (v7 + v5 + 1) >> 1;
2689
+ v5 = (v7 - v5 + 1) >> 1;
2690
+ v7 = t;
2691
+
2692
+ // stage 2
2693
+ t = (v0 - v3 + 1) >> 1;
2694
+ v0 = (v0 + v3 + 1) >> 1;
2695
+ v3 = t;
2696
+ t = (v1 - v2 + 1) >> 1;
2697
+ v1 = (v1 + v2 + 1) >> 1;
2698
+ v2 = t;
2699
+ t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2700
+ v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2701
+ v7 = t;
2702
+ t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2703
+ v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2704
+ v6 = t;
2705
+
2706
+ // stage 1
2707
+ p[0] = v0 + v7;
2708
+ p[7] = v0 - v7;
2709
+ p[1] = v1 + v6;
2710
+ p[6] = v1 - v6;
2711
+ p[2] = v2 + v5;
2712
+ p[5] = v2 - v5;
2713
+ p[3] = v3 + v4;
2714
+ p[4] = v3 - v4;
2715
+ }
2716
+
2717
+ // inverse DCT on columns
2718
+ for (i = 0; i < 8; ++i) {
2719
+ p = dataIn + i;
2720
+
2721
+ // check for all-zero AC coefficients
2722
+ if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 &&
2723
+ p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) {
2724
+ t = (dctSqrt2 * dataIn[i+0] + 8192) >> 14;
2725
+ p[0*8] = t;
2726
+ p[1*8] = t;
2727
+ p[2*8] = t;
2728
+ p[3*8] = t;
2729
+ p[4*8] = t;
2730
+ p[5*8] = t;
2731
+ p[6*8] = t;
2732
+ p[7*8] = t;
2733
+ continue;
2734
+ }
2735
+
2736
+ // stage 4
2737
+ v0 = (dctSqrt2 * p[0*8] + 2048) >> 12;
2738
+ v1 = (dctSqrt2 * p[4*8] + 2048) >> 12;
2739
+ v2 = p[2*8];
2740
+ v3 = p[6*8];
2741
+ v4 = (dctSqrt1d2 * (p[1*8] - p[7*8]) + 2048) >> 12;
2742
+ v7 = (dctSqrt1d2 * (p[1*8] + p[7*8]) + 2048) >> 12;
2743
+ v5 = p[3*8];
2744
+ v6 = p[5*8];
2745
+
2746
+ // stage 3
2747
+ t = (v0 - v1 + 1) >> 1;
2748
+ v0 = (v0 + v1 + 1) >> 1;
2749
+ v1 = t;
2750
+ t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
2751
+ v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
2752
+ v3 = t;
2753
+ t = (v4 - v6 + 1) >> 1;
2754
+ v4 = (v4 + v6 + 1) >> 1;
2755
+ v6 = t;
2756
+ t = (v7 + v5 + 1) >> 1;
2757
+ v5 = (v7 - v5 + 1) >> 1;
2758
+ v7 = t;
2759
+
2760
+ // stage 2
2761
+ t = (v0 - v3 + 1) >> 1;
2762
+ v0 = (v0 + v3 + 1) >> 1;
2763
+ v3 = t;
2764
+ t = (v1 - v2 + 1) >> 1;
2765
+ v1 = (v1 + v2 + 1) >> 1;
2766
+ v2 = t;
2767
+ t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2768
+ v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2769
+ v7 = t;
2770
+ t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2771
+ v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2772
+ v6 = t;
2773
+
2774
+ // stage 1
2775
+ p[0*8] = v0 + v7;
2776
+ p[7*8] = v0 - v7;
2777
+ p[1*8] = v1 + v6;
2778
+ p[6*8] = v1 - v6;
2779
+ p[2*8] = v2 + v5;
2780
+ p[5*8] = v2 - v5;
2781
+ p[3*8] = v3 + v4;
2782
+ p[4*8] = v3 - v4;
2783
+ }
2784
+
2785
+ // convert to 8-bit integers
2786
+ for (i = 0; i < 64; ++i) {
2787
+ dataOut[i] = dctClip[dctClipOffset + 128 + ((dataIn[i] + 8) >> 4)];
2788
+ }
2789
+ }
2790
+
2791
+ int DCTStream::readHuffSym(DCTHuffTable *table) {
2792
+ Gushort code;
2793
+ int bit;
2794
+ int codeBits;
2795
+
2796
+ code = 0;
2797
+ codeBits = 0;
2798
+ do {
2799
+ // add a bit to the code
2800
+ if ((bit = readBit()) == EOF)
2801
+ return 9999;
2802
+ code = (code << 1) + bit;
2803
+ ++codeBits;
2804
+
2805
+ // look up code
2806
+ if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
2807
+ code -= table->firstCode[codeBits];
2808
+ return table->sym[table->firstSym[codeBits] + code];
2809
+ }
2810
+ } while (codeBits < 16);
2811
+
2812
+ error(getPos(), "Bad Huffman code in DCT stream");
2813
+ return 9999;
2814
+ }
2815
+
2816
+ int DCTStream::readAmp(int size) {
2817
+ int amp, bit;
2818
+ int bits;
2819
+
2820
+ amp = 0;
2821
+ for (bits = 0; bits < size; ++bits) {
2822
+ if ((bit = readBit()) == EOF)
2823
+ return 9999;
2824
+ amp = (amp << 1) + bit;
2825
+ }
2826
+ if (amp < (1 << (size - 1)))
2827
+ amp -= (1 << size) - 1;
2828
+ return amp;
2829
+ }
2830
+
2831
+ int DCTStream::readBit() {
2832
+ int bit;
2833
+ int c, c2;
2834
+
2835
+ if (inputBits == 0) {
2836
+ if ((c = str->getChar()) == EOF)
2837
+ return EOF;
2838
+ if (c == 0xff) {
2839
+ do {
2840
+ c2 = str->getChar();
2841
+ } while (c2 == 0xff);
2842
+ if (c2 != 0x00) {
2843
+ error(getPos(), "Bad DCT data: missing 00 after ff");
2844
+ return EOF;
2845
+ }
2846
+ }
2847
+ inputBuf = c;
2848
+ inputBits = 8;
2849
+ }
2850
+ bit = (inputBuf >> (inputBits - 1)) & 1;
2851
+ --inputBits;
2852
+ return bit;
2853
+ }
2854
+
2855
+ GBool DCTStream::readHeader() {
2856
+ GBool doScan;
2857
+ int n;
2858
+ int c = 0;
2859
+ int i;
2860
+
2861
+ // read headers
2862
+ doScan = gFalse;
2863
+ while (!doScan) {
2864
+ c = readMarker();
2865
+ switch (c) {
2866
+ case 0xc0: // SOF0 (sequential)
2867
+ case 0xc1: // SOF1 (extended sequential)
2868
+ if (!readBaselineSOF()) {
2869
+ return gFalse;
2870
+ }
2871
+ break;
2872
+ case 0xc2: // SOF2 (progressive)
2873
+ if (!readProgressiveSOF()) {
2874
+ return gFalse;
2875
+ }
2876
+ break;
2877
+ case 0xc4: // DHT
2878
+ if (!readHuffmanTables()) {
2879
+ return gFalse;
2880
+ }
2881
+ break;
2882
+ case 0xd8: // SOI
2883
+ break;
2884
+ case 0xd9: // EOI
2885
+ return gFalse;
2886
+ case 0xda: // SOS
2887
+ if (!readScanInfo()) {
2888
+ return gFalse;
2889
+ }
2890
+ doScan = gTrue;
2891
+ break;
2892
+ case 0xdb: // DQT
2893
+ if (!readQuantTables()) {
2894
+ return gFalse;
2895
+ }
2896
+ break;
2897
+ case 0xdd: // DRI
2898
+ if (!readRestartInterval()) {
2899
+ return gFalse;
2900
+ }
2901
+ break;
2902
+ case 0xe0: // APP0
2903
+ if (!readJFIFMarker()) {
2904
+ return gFalse;
2905
+ }
2906
+ break;
2907
+ case 0xee: // APP14
2908
+ if (!readAdobeMarker()) {
2909
+ return gFalse;
2910
+ }
2911
+ break;
2912
+ case EOF:
2913
+ error(getPos(), "Bad DCT header");
2914
+ return gFalse;
2915
+ default:
2916
+ // skip APPn / COM / etc.
2917
+ if (c >= 0xe0) {
2918
+ n = read16() - 2;
2919
+ for (i = 0; i < n; ++i) {
2920
+ str->getChar();
2921
+ }
2922
+ } else {
2923
+ error(getPos(), "Unknown DCT marker <%02x>", c);
2924
+ return gFalse;
2925
+ }
2926
+ break;
2927
+ }
2928
+ }
2929
+
2930
+ return gTrue;
2931
+ }
2932
+
2933
+ GBool DCTStream::readBaselineSOF() {
2934
+ int length;
2935
+ int prec;
2936
+ int i;
2937
+ int c;
2938
+
2939
+ length = read16();
2940
+ prec = str->getChar();
2941
+ height = read16();
2942
+ width = read16();
2943
+ numComps = str->getChar();
2944
+ if (numComps <= 0 || numComps > 4) {
2945
+ error(getPos(), "Bad number of components in DCT stream");
2946
+ numComps = 0;
2947
+ return gFalse;
2948
+ }
2949
+ if (prec != 8) {
2950
+ error(getPos(), "Bad DCT precision %d", prec);
2951
+ return gFalse;
2952
+ }
2953
+ for (i = 0; i < numComps; ++i) {
2954
+ compInfo[i].id = str->getChar();
2955
+ c = str->getChar();
2956
+ compInfo[i].hSample = (c >> 4) & 0x0f;
2957
+ compInfo[i].vSample = c & 0x0f;
2958
+ compInfo[i].quantTable = str->getChar();
2959
+ }
2960
+ progressive = gFalse;
2961
+ return gTrue;
2962
+ }
2963
+
2964
+ GBool DCTStream::readProgressiveSOF() {
2965
+ int length;
2966
+ int prec;
2967
+ int i;
2968
+ int c;
2969
+
2970
+ length = read16();
2971
+ prec = str->getChar();
2972
+ height = read16();
2973
+ width = read16();
2974
+ numComps = str->getChar();
2975
+ if (numComps <= 0 || numComps > 4) {
2976
+ error(getPos(), "Bad number of components in DCT stream");
2977
+ numComps = 0;
2978
+ return gFalse;
2979
+ }
2980
+ if (prec != 8) {
2981
+ error(getPos(), "Bad DCT precision %d", prec);
2982
+ return gFalse;
2983
+ }
2984
+ for (i = 0; i < numComps; ++i) {
2985
+ compInfo[i].id = str->getChar();
2986
+ c = str->getChar();
2987
+ compInfo[i].hSample = (c >> 4) & 0x0f;
2988
+ compInfo[i].vSample = c & 0x0f;
2989
+ compInfo[i].quantTable = str->getChar();
2990
+ }
2991
+ progressive = gTrue;
2992
+ return gTrue;
2993
+ }
2994
+
2995
+ GBool DCTStream::readScanInfo() {
2996
+ int length;
2997
+ int id, c;
2998
+ int i, j;
2999
+
3000
+ length = read16() - 2;
3001
+ scanInfo.numComps = str->getChar();
3002
+ if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
3003
+ error(getPos(), "Bad number of components in DCT stream");
3004
+ scanInfo.numComps = 0;
3005
+ return gFalse;
3006
+ }
3007
+ --length;
3008
+ if (length != 2 * scanInfo.numComps + 3) {
3009
+ error(getPos(), "Bad DCT scan info block");
3010
+ return gFalse;
3011
+ }
3012
+ interleaved = scanInfo.numComps == numComps;
3013
+ for (j = 0; j < numComps; ++j) {
3014
+ scanInfo.comp[j] = gFalse;
3015
+ }
3016
+ for (i = 0; i < scanInfo.numComps; ++i) {
3017
+ id = str->getChar();
3018
+ // some (broken) DCT streams reuse ID numbers, but at least they
3019
+ // keep the components in order, so we check compInfo[i] first to
3020
+ // work around the problem
3021
+ if (id == compInfo[i].id) {
3022
+ j = i;
3023
+ } else {
3024
+ for (j = 0; j < numComps; ++j) {
3025
+ if (id == compInfo[j].id) {
3026
+ break;
3027
+ }
3028
+ }
3029
+ if (j == numComps) {
3030
+ error(getPos(), "Bad DCT component ID in scan info block");
3031
+ return gFalse;
3032
+ }
3033
+ }
3034
+ scanInfo.comp[j] = gTrue;
3035
+ c = str->getChar();
3036
+ scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
3037
+ scanInfo.acHuffTable[j] = c & 0x0f;
3038
+ }
3039
+ scanInfo.firstCoeff = str->getChar();
3040
+ scanInfo.lastCoeff = str->getChar();
3041
+ c = str->getChar();
3042
+ scanInfo.ah = (c >> 4) & 0x0f;
3043
+ scanInfo.al = c & 0x0f;
3044
+ return gTrue;
3045
+ }
3046
+
3047
+ GBool DCTStream::readQuantTables() {
3048
+ int length, prec, i, index;
3049
+
3050
+ length = read16() - 2;
3051
+ while (length > 0) {
3052
+ index = str->getChar();
3053
+ prec = (index >> 4) & 0x0f;
3054
+ index &= 0x0f;
3055
+ if (prec > 1 || index >= 4) {
3056
+ error(getPos(), "Bad DCT quantization table");
3057
+ return gFalse;
3058
+ }
3059
+ if (index == numQuantTables) {
3060
+ numQuantTables = index + 1;
3061
+ }
3062
+ for (i = 0; i < 64; ++i) {
3063
+ if (prec) {
3064
+ quantTables[index][dctZigZag[i]] = read16();
3065
+ } else {
3066
+ quantTables[index][dctZigZag[i]] = str->getChar();
3067
+ }
3068
+ }
3069
+ if (prec) {
3070
+ length -= 129;
3071
+ } else {
3072
+ length -= 65;
3073
+ }
3074
+ }
3075
+ return gTrue;
3076
+ }
3077
+
3078
+ GBool DCTStream::readHuffmanTables() {
3079
+ DCTHuffTable *tbl;
3080
+ int length;
3081
+ int index;
3082
+ Gushort code;
3083
+ Guchar sym;
3084
+ int i;
3085
+ int c;
3086
+
3087
+ length = read16() - 2;
3088
+ while (length > 0) {
3089
+ index = str->getChar();
3090
+ --length;
3091
+ if ((index & 0x0f) >= 4) {
3092
+ error(getPos(), "Bad DCT Huffman table");
3093
+ return gFalse;
3094
+ }
3095
+ if (index & 0x10) {
3096
+ index &= 0x0f;
3097
+ if (index >= numACHuffTables)
3098
+ numACHuffTables = index+1;
3099
+ tbl = &acHuffTables[index];
3100
+ } else {
3101
+ index &= 0x0f;
3102
+ if (index >= numDCHuffTables)
3103
+ numDCHuffTables = index+1;
3104
+ tbl = &dcHuffTables[index];
3105
+ }
3106
+ sym = 0;
3107
+ code = 0;
3108
+ for (i = 1; i <= 16; ++i) {
3109
+ c = str->getChar();
3110
+ tbl->firstSym[i] = sym;
3111
+ tbl->firstCode[i] = code;
3112
+ tbl->numCodes[i] = c;
3113
+ sym += c;
3114
+ code = (code + c) << 1;
3115
+ }
3116
+ length -= 16;
3117
+ for (i = 0; i < sym; ++i)
3118
+ tbl->sym[i] = str->getChar();
3119
+ length -= sym;
3120
+ }
3121
+ return gTrue;
3122
+ }
3123
+
3124
+ GBool DCTStream::readRestartInterval() {
3125
+ int length;
3126
+
3127
+ length = read16();
3128
+ if (length != 4) {
3129
+ error(getPos(), "Bad DCT restart interval");
3130
+ return gFalse;
3131
+ }
3132
+ restartInterval = read16();
3133
+ return gTrue;
3134
+ }
3135
+
3136
+ GBool DCTStream::readJFIFMarker() {
3137
+ int length, i;
3138
+ char buf[5];
3139
+ int c;
3140
+
3141
+ length = read16();
3142
+ length -= 2;
3143
+ if (length >= 5) {
3144
+ for (i = 0; i < 5; ++i) {
3145
+ if ((c = str->getChar()) == EOF) {
3146
+ error(getPos(), "Bad DCT APP0 marker");
3147
+ return gFalse;
3148
+ }
3149
+ buf[i] = c;
3150
+ }
3151
+ length -= 5;
3152
+ if (!memcmp(buf, "JFIF\0", 5)) {
3153
+ gotJFIFMarker = gTrue;
3154
+ }
3155
+ }
3156
+ while (length > 0) {
3157
+ if (str->getChar() == EOF) {
3158
+ error(getPos(), "Bad DCT APP0 marker");
3159
+ return gFalse;
3160
+ }
3161
+ --length;
3162
+ }
3163
+ return gTrue;
3164
+ }
3165
+
3166
+ GBool DCTStream::readAdobeMarker() {
3167
+ int length, i;
3168
+ char buf[12];
3169
+ int c;
3170
+
3171
+ length = read16();
3172
+ if (length < 14) {
3173
+ goto err;
3174
+ }
3175
+ for (i = 0; i < 12; ++i) {
3176
+ if ((c = str->getChar()) == EOF) {
3177
+ goto err;
3178
+ }
3179
+ buf[i] = c;
3180
+ }
3181
+ if (strncmp(buf, "Adobe", 5)) {
3182
+ goto err;
3183
+ }
3184
+ colorXform = buf[11];
3185
+ gotAdobeMarker = gTrue;
3186
+ for (i = 14; i < length; ++i) {
3187
+ if (str->getChar() == EOF) {
3188
+ goto err;
3189
+ }
3190
+ }
3191
+ return gTrue;
3192
+
3193
+ err:
3194
+ error(getPos(), "Bad DCT Adobe APP14 marker");
3195
+ return gFalse;
3196
+ }
3197
+
3198
+ GBool DCTStream::readTrailer() {
3199
+ int c;
3200
+
3201
+ c = readMarker();
3202
+ if (c != 0xd9) { // EOI
3203
+ error(getPos(), "Bad DCT trailer");
3204
+ return gFalse;
3205
+ }
3206
+ return gTrue;
3207
+ }
3208
+
3209
+ int DCTStream::readMarker() {
3210
+ int c;
3211
+
3212
+ do {
3213
+ do {
3214
+ c = str->getChar();
3215
+ } while (c != 0xff && c != EOF);
3216
+ do {
3217
+ c = str->getChar();
3218
+ } while (c == 0xff);
3219
+ } while (c == 0x00);
3220
+ return c;
3221
+ }
3222
+
3223
+ int DCTStream::read16() {
3224
+ int c1, c2;
3225
+
3226
+ if ((c1 = str->getChar()) == EOF)
3227
+ return EOF;
3228
+ if ((c2 = str->getChar()) == EOF)
3229
+ return EOF;
3230
+ return (c1 << 8) + c2;
3231
+ }
3232
+
3233
+ GString *DCTStream::getPSFilter(int psLevel, char *indent) {
3234
+ GString *s;
3235
+
3236
+ if (psLevel < 2) {
3237
+ return NULL;
3238
+ }
3239
+ if (!(s = str->getPSFilter(psLevel, indent))) {
3240
+ return NULL;
3241
+ }
3242
+ s->append(indent)->append("<< >> /DCTDecode filter\n");
3243
+ return s;
3244
+ }
3245
+
3246
+ GBool DCTStream::isBinary(GBool last) {
3247
+ return str->isBinary(gTrue);
3248
+ }
3249
+
3250
+ //------------------------------------------------------------------------
3251
+ // FlateStream
3252
+ //------------------------------------------------------------------------
3253
+
3254
+ int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
3255
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
3256
+ };
3257
+
3258
+ FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
3259
+ {0, 3},
3260
+ {0, 4},
3261
+ {0, 5},
3262
+ {0, 6},
3263
+ {0, 7},
3264
+ {0, 8},
3265
+ {0, 9},
3266
+ {0, 10},
3267
+ {1, 11},
3268
+ {1, 13},
3269
+ {1, 15},
3270
+ {1, 17},
3271
+ {2, 19},
3272
+ {2, 23},
3273
+ {2, 27},
3274
+ {2, 31},
3275
+ {3, 35},
3276
+ {3, 43},
3277
+ {3, 51},
3278
+ {3, 59},
3279
+ {4, 67},
3280
+ {4, 83},
3281
+ {4, 99},
3282
+ {4, 115},
3283
+ {5, 131},
3284
+ {5, 163},
3285
+ {5, 195},
3286
+ {5, 227},
3287
+ {0, 258},
3288
+ {0, 258},
3289
+ {0, 258}
3290
+ };
3291
+
3292
+ FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
3293
+ { 0, 1},
3294
+ { 0, 2},
3295
+ { 0, 3},
3296
+ { 0, 4},
3297
+ { 1, 5},
3298
+ { 1, 7},
3299
+ { 2, 9},
3300
+ { 2, 13},
3301
+ { 3, 17},
3302
+ { 3, 25},
3303
+ { 4, 33},
3304
+ { 4, 49},
3305
+ { 5, 65},
3306
+ { 5, 97},
3307
+ { 6, 129},
3308
+ { 6, 193},
3309
+ { 7, 257},
3310
+ { 7, 385},
3311
+ { 8, 513},
3312
+ { 8, 769},
3313
+ { 9, 1025},
3314
+ { 9, 1537},
3315
+ {10, 2049},
3316
+ {10, 3073},
3317
+ {11, 4097},
3318
+ {11, 6145},
3319
+ {12, 8193},
3320
+ {12, 12289},
3321
+ {13, 16385},
3322
+ {13, 24577}
3323
+ };
3324
+
3325
+ static FlateCode flateFixedLitCodeTabCodes[512] = {
3326
+ {7, 0x0100},
3327
+ {8, 0x0050},
3328
+ {8, 0x0010},
3329
+ {8, 0x0118},
3330
+ {7, 0x0110},
3331
+ {8, 0x0070},
3332
+ {8, 0x0030},
3333
+ {9, 0x00c0},
3334
+ {7, 0x0108},
3335
+ {8, 0x0060},
3336
+ {8, 0x0020},
3337
+ {9, 0x00a0},
3338
+ {8, 0x0000},
3339
+ {8, 0x0080},
3340
+ {8, 0x0040},
3341
+ {9, 0x00e0},
3342
+ {7, 0x0104},
3343
+ {8, 0x0058},
3344
+ {8, 0x0018},
3345
+ {9, 0x0090},
3346
+ {7, 0x0114},
3347
+ {8, 0x0078},
3348
+ {8, 0x0038},
3349
+ {9, 0x00d0},
3350
+ {7, 0x010c},
3351
+ {8, 0x0068},
3352
+ {8, 0x0028},
3353
+ {9, 0x00b0},
3354
+ {8, 0x0008},
3355
+ {8, 0x0088},
3356
+ {8, 0x0048},
3357
+ {9, 0x00f0},
3358
+ {7, 0x0102},
3359
+ {8, 0x0054},
3360
+ {8, 0x0014},
3361
+ {8, 0x011c},
3362
+ {7, 0x0112},
3363
+ {8, 0x0074},
3364
+ {8, 0x0034},
3365
+ {9, 0x00c8},
3366
+ {7, 0x010a},
3367
+ {8, 0x0064},
3368
+ {8, 0x0024},
3369
+ {9, 0x00a8},
3370
+ {8, 0x0004},
3371
+ {8, 0x0084},
3372
+ {8, 0x0044},
3373
+ {9, 0x00e8},
3374
+ {7, 0x0106},
3375
+ {8, 0x005c},
3376
+ {8, 0x001c},
3377
+ {9, 0x0098},
3378
+ {7, 0x0116},
3379
+ {8, 0x007c},
3380
+ {8, 0x003c},
3381
+ {9, 0x00d8},
3382
+ {7, 0x010e},
3383
+ {8, 0x006c},
3384
+ {8, 0x002c},
3385
+ {9, 0x00b8},
3386
+ {8, 0x000c},
3387
+ {8, 0x008c},
3388
+ {8, 0x004c},
3389
+ {9, 0x00f8},
3390
+ {7, 0x0101},
3391
+ {8, 0x0052},
3392
+ {8, 0x0012},
3393
+ {8, 0x011a},
3394
+ {7, 0x0111},
3395
+ {8, 0x0072},
3396
+ {8, 0x0032},
3397
+ {9, 0x00c4},
3398
+ {7, 0x0109},
3399
+ {8, 0x0062},
3400
+ {8, 0x0022},
3401
+ {9, 0x00a4},
3402
+ {8, 0x0002},
3403
+ {8, 0x0082},
3404
+ {8, 0x0042},
3405
+ {9, 0x00e4},
3406
+ {7, 0x0105},
3407
+ {8, 0x005a},
3408
+ {8, 0x001a},
3409
+ {9, 0x0094},
3410
+ {7, 0x0115},
3411
+ {8, 0x007a},
3412
+ {8, 0x003a},
3413
+ {9, 0x00d4},
3414
+ {7, 0x010d},
3415
+ {8, 0x006a},
3416
+ {8, 0x002a},
3417
+ {9, 0x00b4},
3418
+ {8, 0x000a},
3419
+ {8, 0x008a},
3420
+ {8, 0x004a},
3421
+ {9, 0x00f4},
3422
+ {7, 0x0103},
3423
+ {8, 0x0056},
3424
+ {8, 0x0016},
3425
+ {8, 0x011e},
3426
+ {7, 0x0113},
3427
+ {8, 0x0076},
3428
+ {8, 0x0036},
3429
+ {9, 0x00cc},
3430
+ {7, 0x010b},
3431
+ {8, 0x0066},
3432
+ {8, 0x0026},
3433
+ {9, 0x00ac},
3434
+ {8, 0x0006},
3435
+ {8, 0x0086},
3436
+ {8, 0x0046},
3437
+ {9, 0x00ec},
3438
+ {7, 0x0107},
3439
+ {8, 0x005e},
3440
+ {8, 0x001e},
3441
+ {9, 0x009c},
3442
+ {7, 0x0117},
3443
+ {8, 0x007e},
3444
+ {8, 0x003e},
3445
+ {9, 0x00dc},
3446
+ {7, 0x010f},
3447
+ {8, 0x006e},
3448
+ {8, 0x002e},
3449
+ {9, 0x00bc},
3450
+ {8, 0x000e},
3451
+ {8, 0x008e},
3452
+ {8, 0x004e},
3453
+ {9, 0x00fc},
3454
+ {7, 0x0100},
3455
+ {8, 0x0051},
3456
+ {8, 0x0011},
3457
+ {8, 0x0119},
3458
+ {7, 0x0110},
3459
+ {8, 0x0071},
3460
+ {8, 0x0031},
3461
+ {9, 0x00c2},
3462
+ {7, 0x0108},
3463
+ {8, 0x0061},
3464
+ {8, 0x0021},
3465
+ {9, 0x00a2},
3466
+ {8, 0x0001},
3467
+ {8, 0x0081},
3468
+ {8, 0x0041},
3469
+ {9, 0x00e2},
3470
+ {7, 0x0104},
3471
+ {8, 0x0059},
3472
+ {8, 0x0019},
3473
+ {9, 0x0092},
3474
+ {7, 0x0114},
3475
+ {8, 0x0079},
3476
+ {8, 0x0039},
3477
+ {9, 0x00d2},
3478
+ {7, 0x010c},
3479
+ {8, 0x0069},
3480
+ {8, 0x0029},
3481
+ {9, 0x00b2},
3482
+ {8, 0x0009},
3483
+ {8, 0x0089},
3484
+ {8, 0x0049},
3485
+ {9, 0x00f2},
3486
+ {7, 0x0102},
3487
+ {8, 0x0055},
3488
+ {8, 0x0015},
3489
+ {8, 0x011d},
3490
+ {7, 0x0112},
3491
+ {8, 0x0075},
3492
+ {8, 0x0035},
3493
+ {9, 0x00ca},
3494
+ {7, 0x010a},
3495
+ {8, 0x0065},
3496
+ {8, 0x0025},
3497
+ {9, 0x00aa},
3498
+ {8, 0x0005},
3499
+ {8, 0x0085},
3500
+ {8, 0x0045},
3501
+ {9, 0x00ea},
3502
+ {7, 0x0106},
3503
+ {8, 0x005d},
3504
+ {8, 0x001d},
3505
+ {9, 0x009a},
3506
+ {7, 0x0116},
3507
+ {8, 0x007d},
3508
+ {8, 0x003d},
3509
+ {9, 0x00da},
3510
+ {7, 0x010e},
3511
+ {8, 0x006d},
3512
+ {8, 0x002d},
3513
+ {9, 0x00ba},
3514
+ {8, 0x000d},
3515
+ {8, 0x008d},
3516
+ {8, 0x004d},
3517
+ {9, 0x00fa},
3518
+ {7, 0x0101},
3519
+ {8, 0x0053},
3520
+ {8, 0x0013},
3521
+ {8, 0x011b},
3522
+ {7, 0x0111},
3523
+ {8, 0x0073},
3524
+ {8, 0x0033},
3525
+ {9, 0x00c6},
3526
+ {7, 0x0109},
3527
+ {8, 0x0063},
3528
+ {8, 0x0023},
3529
+ {9, 0x00a6},
3530
+ {8, 0x0003},
3531
+ {8, 0x0083},
3532
+ {8, 0x0043},
3533
+ {9, 0x00e6},
3534
+ {7, 0x0105},
3535
+ {8, 0x005b},
3536
+ {8, 0x001b},
3537
+ {9, 0x0096},
3538
+ {7, 0x0115},
3539
+ {8, 0x007b},
3540
+ {8, 0x003b},
3541
+ {9, 0x00d6},
3542
+ {7, 0x010d},
3543
+ {8, 0x006b},
3544
+ {8, 0x002b},
3545
+ {9, 0x00b6},
3546
+ {8, 0x000b},
3547
+ {8, 0x008b},
3548
+ {8, 0x004b},
3549
+ {9, 0x00f6},
3550
+ {7, 0x0103},
3551
+ {8, 0x0057},
3552
+ {8, 0x0017},
3553
+ {8, 0x011f},
3554
+ {7, 0x0113},
3555
+ {8, 0x0077},
3556
+ {8, 0x0037},
3557
+ {9, 0x00ce},
3558
+ {7, 0x010b},
3559
+ {8, 0x0067},
3560
+ {8, 0x0027},
3561
+ {9, 0x00ae},
3562
+ {8, 0x0007},
3563
+ {8, 0x0087},
3564
+ {8, 0x0047},
3565
+ {9, 0x00ee},
3566
+ {7, 0x0107},
3567
+ {8, 0x005f},
3568
+ {8, 0x001f},
3569
+ {9, 0x009e},
3570
+ {7, 0x0117},
3571
+ {8, 0x007f},
3572
+ {8, 0x003f},
3573
+ {9, 0x00de},
3574
+ {7, 0x010f},
3575
+ {8, 0x006f},
3576
+ {8, 0x002f},
3577
+ {9, 0x00be},
3578
+ {8, 0x000f},
3579
+ {8, 0x008f},
3580
+ {8, 0x004f},
3581
+ {9, 0x00fe},
3582
+ {7, 0x0100},
3583
+ {8, 0x0050},
3584
+ {8, 0x0010},
3585
+ {8, 0x0118},
3586
+ {7, 0x0110},
3587
+ {8, 0x0070},
3588
+ {8, 0x0030},
3589
+ {9, 0x00c1},
3590
+ {7, 0x0108},
3591
+ {8, 0x0060},
3592
+ {8, 0x0020},
3593
+ {9, 0x00a1},
3594
+ {8, 0x0000},
3595
+ {8, 0x0080},
3596
+ {8, 0x0040},
3597
+ {9, 0x00e1},
3598
+ {7, 0x0104},
3599
+ {8, 0x0058},
3600
+ {8, 0x0018},
3601
+ {9, 0x0091},
3602
+ {7, 0x0114},
3603
+ {8, 0x0078},
3604
+ {8, 0x0038},
3605
+ {9, 0x00d1},
3606
+ {7, 0x010c},
3607
+ {8, 0x0068},
3608
+ {8, 0x0028},
3609
+ {9, 0x00b1},
3610
+ {8, 0x0008},
3611
+ {8, 0x0088},
3612
+ {8, 0x0048},
3613
+ {9, 0x00f1},
3614
+ {7, 0x0102},
3615
+ {8, 0x0054},
3616
+ {8, 0x0014},
3617
+ {8, 0x011c},
3618
+ {7, 0x0112},
3619
+ {8, 0x0074},
3620
+ {8, 0x0034},
3621
+ {9, 0x00c9},
3622
+ {7, 0x010a},
3623
+ {8, 0x0064},
3624
+ {8, 0x0024},
3625
+ {9, 0x00a9},
3626
+ {8, 0x0004},
3627
+ {8, 0x0084},
3628
+ {8, 0x0044},
3629
+ {9, 0x00e9},
3630
+ {7, 0x0106},
3631
+ {8, 0x005c},
3632
+ {8, 0x001c},
3633
+ {9, 0x0099},
3634
+ {7, 0x0116},
3635
+ {8, 0x007c},
3636
+ {8, 0x003c},
3637
+ {9, 0x00d9},
3638
+ {7, 0x010e},
3639
+ {8, 0x006c},
3640
+ {8, 0x002c},
3641
+ {9, 0x00b9},
3642
+ {8, 0x000c},
3643
+ {8, 0x008c},
3644
+ {8, 0x004c},
3645
+ {9, 0x00f9},
3646
+ {7, 0x0101},
3647
+ {8, 0x0052},
3648
+ {8, 0x0012},
3649
+ {8, 0x011a},
3650
+ {7, 0x0111},
3651
+ {8, 0x0072},
3652
+ {8, 0x0032},
3653
+ {9, 0x00c5},
3654
+ {7, 0x0109},
3655
+ {8, 0x0062},
3656
+ {8, 0x0022},
3657
+ {9, 0x00a5},
3658
+ {8, 0x0002},
3659
+ {8, 0x0082},
3660
+ {8, 0x0042},
3661
+ {9, 0x00e5},
3662
+ {7, 0x0105},
3663
+ {8, 0x005a},
3664
+ {8, 0x001a},
3665
+ {9, 0x0095},
3666
+ {7, 0x0115},
3667
+ {8, 0x007a},
3668
+ {8, 0x003a},
3669
+ {9, 0x00d5},
3670
+ {7, 0x010d},
3671
+ {8, 0x006a},
3672
+ {8, 0x002a},
3673
+ {9, 0x00b5},
3674
+ {8, 0x000a},
3675
+ {8, 0x008a},
3676
+ {8, 0x004a},
3677
+ {9, 0x00f5},
3678
+ {7, 0x0103},
3679
+ {8, 0x0056},
3680
+ {8, 0x0016},
3681
+ {8, 0x011e},
3682
+ {7, 0x0113},
3683
+ {8, 0x0076},
3684
+ {8, 0x0036},
3685
+ {9, 0x00cd},
3686
+ {7, 0x010b},
3687
+ {8, 0x0066},
3688
+ {8, 0x0026},
3689
+ {9, 0x00ad},
3690
+ {8, 0x0006},
3691
+ {8, 0x0086},
3692
+ {8, 0x0046},
3693
+ {9, 0x00ed},
3694
+ {7, 0x0107},
3695
+ {8, 0x005e},
3696
+ {8, 0x001e},
3697
+ {9, 0x009d},
3698
+ {7, 0x0117},
3699
+ {8, 0x007e},
3700
+ {8, 0x003e},
3701
+ {9, 0x00dd},
3702
+ {7, 0x010f},
3703
+ {8, 0x006e},
3704
+ {8, 0x002e},
3705
+ {9, 0x00bd},
3706
+ {8, 0x000e},
3707
+ {8, 0x008e},
3708
+ {8, 0x004e},
3709
+ {9, 0x00fd},
3710
+ {7, 0x0100},
3711
+ {8, 0x0051},
3712
+ {8, 0x0011},
3713
+ {8, 0x0119},
3714
+ {7, 0x0110},
3715
+ {8, 0x0071},
3716
+ {8, 0x0031},
3717
+ {9, 0x00c3},
3718
+ {7, 0x0108},
3719
+ {8, 0x0061},
3720
+ {8, 0x0021},
3721
+ {9, 0x00a3},
3722
+ {8, 0x0001},
3723
+ {8, 0x0081},
3724
+ {8, 0x0041},
3725
+ {9, 0x00e3},
3726
+ {7, 0x0104},
3727
+ {8, 0x0059},
3728
+ {8, 0x0019},
3729
+ {9, 0x0093},
3730
+ {7, 0x0114},
3731
+ {8, 0x0079},
3732
+ {8, 0x0039},
3733
+ {9, 0x00d3},
3734
+ {7, 0x010c},
3735
+ {8, 0x0069},
3736
+ {8, 0x0029},
3737
+ {9, 0x00b3},
3738
+ {8, 0x0009},
3739
+ {8, 0x0089},
3740
+ {8, 0x0049},
3741
+ {9, 0x00f3},
3742
+ {7, 0x0102},
3743
+ {8, 0x0055},
3744
+ {8, 0x0015},
3745
+ {8, 0x011d},
3746
+ {7, 0x0112},
3747
+ {8, 0x0075},
3748
+ {8, 0x0035},
3749
+ {9, 0x00cb},
3750
+ {7, 0x010a},
3751
+ {8, 0x0065},
3752
+ {8, 0x0025},
3753
+ {9, 0x00ab},
3754
+ {8, 0x0005},
3755
+ {8, 0x0085},
3756
+ {8, 0x0045},
3757
+ {9, 0x00eb},
3758
+ {7, 0x0106},
3759
+ {8, 0x005d},
3760
+ {8, 0x001d},
3761
+ {9, 0x009b},
3762
+ {7, 0x0116},
3763
+ {8, 0x007d},
3764
+ {8, 0x003d},
3765
+ {9, 0x00db},
3766
+ {7, 0x010e},
3767
+ {8, 0x006d},
3768
+ {8, 0x002d},
3769
+ {9, 0x00bb},
3770
+ {8, 0x000d},
3771
+ {8, 0x008d},
3772
+ {8, 0x004d},
3773
+ {9, 0x00fb},
3774
+ {7, 0x0101},
3775
+ {8, 0x0053},
3776
+ {8, 0x0013},
3777
+ {8, 0x011b},
3778
+ {7, 0x0111},
3779
+ {8, 0x0073},
3780
+ {8, 0x0033},
3781
+ {9, 0x00c7},
3782
+ {7, 0x0109},
3783
+ {8, 0x0063},
3784
+ {8, 0x0023},
3785
+ {9, 0x00a7},
3786
+ {8, 0x0003},
3787
+ {8, 0x0083},
3788
+ {8, 0x0043},
3789
+ {9, 0x00e7},
3790
+ {7, 0x0105},
3791
+ {8, 0x005b},
3792
+ {8, 0x001b},
3793
+ {9, 0x0097},
3794
+ {7, 0x0115},
3795
+ {8, 0x007b},
3796
+ {8, 0x003b},
3797
+ {9, 0x00d7},
3798
+ {7, 0x010d},
3799
+ {8, 0x006b},
3800
+ {8, 0x002b},
3801
+ {9, 0x00b7},
3802
+ {8, 0x000b},
3803
+ {8, 0x008b},
3804
+ {8, 0x004b},
3805
+ {9, 0x00f7},
3806
+ {7, 0x0103},
3807
+ {8, 0x0057},
3808
+ {8, 0x0017},
3809
+ {8, 0x011f},
3810
+ {7, 0x0113},
3811
+ {8, 0x0077},
3812
+ {8, 0x0037},
3813
+ {9, 0x00cf},
3814
+ {7, 0x010b},
3815
+ {8, 0x0067},
3816
+ {8, 0x0027},
3817
+ {9, 0x00af},
3818
+ {8, 0x0007},
3819
+ {8, 0x0087},
3820
+ {8, 0x0047},
3821
+ {9, 0x00ef},
3822
+ {7, 0x0107},
3823
+ {8, 0x005f},
3824
+ {8, 0x001f},
3825
+ {9, 0x009f},
3826
+ {7, 0x0117},
3827
+ {8, 0x007f},
3828
+ {8, 0x003f},
3829
+ {9, 0x00df},
3830
+ {7, 0x010f},
3831
+ {8, 0x006f},
3832
+ {8, 0x002f},
3833
+ {9, 0x00bf},
3834
+ {8, 0x000f},
3835
+ {8, 0x008f},
3836
+ {8, 0x004f},
3837
+ {9, 0x00ff}
3838
+ };
3839
+
3840
+ FlateHuffmanTab FlateStream::fixedLitCodeTab = {
3841
+ flateFixedLitCodeTabCodes, 9
3842
+ };
3843
+
3844
+ static FlateCode flateFixedDistCodeTabCodes[32] = {
3845
+ {5, 0x0000},
3846
+ {5, 0x0010},
3847
+ {5, 0x0008},
3848
+ {5, 0x0018},
3849
+ {5, 0x0004},
3850
+ {5, 0x0014},
3851
+ {5, 0x000c},
3852
+ {5, 0x001c},
3853
+ {5, 0x0002},
3854
+ {5, 0x0012},
3855
+ {5, 0x000a},
3856
+ {5, 0x001a},
3857
+ {5, 0x0006},
3858
+ {5, 0x0016},
3859
+ {5, 0x000e},
3860
+ {0, 0x0000},
3861
+ {5, 0x0001},
3862
+ {5, 0x0011},
3863
+ {5, 0x0009},
3864
+ {5, 0x0019},
3865
+ {5, 0x0005},
3866
+ {5, 0x0015},
3867
+ {5, 0x000d},
3868
+ {5, 0x001d},
3869
+ {5, 0x0003},
3870
+ {5, 0x0013},
3871
+ {5, 0x000b},
3872
+ {5, 0x001b},
3873
+ {5, 0x0007},
3874
+ {5, 0x0017},
3875
+ {5, 0x000f},
3876
+ {0, 0x0000}
3877
+ };
3878
+
3879
+ FlateHuffmanTab FlateStream::fixedDistCodeTab = {
3880
+ flateFixedDistCodeTabCodes, 5
3881
+ };
3882
+
3883
+ FlateStream::FlateStream(Stream *strA, int predictor, int columns,
3884
+ int colors, int bits):
3885
+ FilterStream(strA) {
3886
+ if (predictor != 1) {
3887
+ pred = new StreamPredictor(this, predictor, columns, colors, bits);
3888
+ if (!pred->isOk()) {
3889
+ delete pred;
3890
+ pred = NULL;
3891
+ }
3892
+ } else {
3893
+ pred = NULL;
3894
+ }
3895
+ litCodeTab.codes = NULL;
3896
+ distCodeTab.codes = NULL;
3897
+ memset(buf, 0, flateWindow);
3898
+ }
3899
+
3900
+ FlateStream::~FlateStream() {
3901
+ if (litCodeTab.codes != fixedLitCodeTab.codes) {
3902
+ gfree(litCodeTab.codes);
3903
+ }
3904
+ if (distCodeTab.codes != fixedDistCodeTab.codes) {
3905
+ gfree(distCodeTab.codes);
3906
+ }
3907
+ if (pred) {
3908
+ delete pred;
3909
+ }
3910
+ delete str;
3911
+ }
3912
+
3913
+ void FlateStream::reset() {
3914
+ int cmf, flg;
3915
+
3916
+ index = 0;
3917
+ remain = 0;
3918
+ codeBuf = 0;
3919
+ codeSize = 0;
3920
+ compressedBlock = gFalse;
3921
+ endOfBlock = gTrue;
3922
+ eof = gTrue;
3923
+
3924
+ str->reset();
3925
+
3926
+ // read header
3927
+ //~ need to look at window size?
3928
+ endOfBlock = eof = gTrue;
3929
+ cmf = str->getChar();
3930
+ flg = str->getChar();
3931
+ if (cmf == EOF || flg == EOF)
3932
+ return;
3933
+ if ((cmf & 0x0f) != 0x08) {
3934
+ error(getPos(), "Unknown compression method in flate stream");
3935
+ return;
3936
+ }
3937
+ if ((((cmf << 8) + flg) % 31) != 0) {
3938
+ error(getPos(), "Bad FCHECK in flate stream");
3939
+ return;
3940
+ }
3941
+ if (flg & 0x20) {
3942
+ error(getPos(), "FDICT bit set in flate stream");
3943
+ return;
3944
+ }
3945
+
3946
+ eof = gFalse;
3947
+ }
3948
+
3949
+ int FlateStream::getChar() {
3950
+ int c;
3951
+
3952
+ if (pred) {
3953
+ return pred->getChar();
3954
+ }
3955
+ while (remain == 0) {
3956
+ if (endOfBlock && eof)
3957
+ return EOF;
3958
+ readSome();
3959
+ }
3960
+ c = buf[index];
3961
+ index = (index + 1) & flateMask;
3962
+ --remain;
3963
+ return c;
3964
+ }
3965
+
3966
+ int FlateStream::lookChar() {
3967
+ int c;
3968
+
3969
+ if (pred) {
3970
+ return pred->lookChar();
3971
+ }
3972
+ while (remain == 0) {
3973
+ if (endOfBlock && eof)
3974
+ return EOF;
3975
+ readSome();
3976
+ }
3977
+ c = buf[index];
3978
+ return c;
3979
+ }
3980
+
3981
+ int FlateStream::getRawChar() {
3982
+ int c;
3983
+
3984
+ while (remain == 0) {
3985
+ if (endOfBlock && eof)
3986
+ return EOF;
3987
+ readSome();
3988
+ }
3989
+ c = buf[index];
3990
+ index = (index + 1) & flateMask;
3991
+ --remain;
3992
+ return c;
3993
+ }
3994
+
3995
+ GString *FlateStream::getPSFilter(int psLevel, char *indent) {
3996
+ GString *s;
3997
+
3998
+ if (psLevel < 3 || pred) {
3999
+ return NULL;
4000
+ }
4001
+ if (!(s = str->getPSFilter(psLevel, indent))) {
4002
+ return NULL;
4003
+ }
4004
+ s->append(indent)->append("<< >> /FlateDecode filter\n");
4005
+ return s;
4006
+ }
4007
+
4008
+ GBool FlateStream::isBinary(GBool last) {
4009
+ return str->isBinary(gTrue);
4010
+ }
4011
+
4012
+ void FlateStream::readSome() {
4013
+ int code1, code2;
4014
+ int len, dist;
4015
+ int i, j, k;
4016
+ int c;
4017
+
4018
+ if (endOfBlock) {
4019
+ if (!startBlock())
4020
+ return;
4021
+ }
4022
+
4023
+ if (compressedBlock) {
4024
+ if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
4025
+ goto err;
4026
+ if (code1 < 256) {
4027
+ buf[index] = code1;
4028
+ remain = 1;
4029
+ } else if (code1 == 256) {
4030
+ endOfBlock = gTrue;
4031
+ remain = 0;
4032
+ } else {
4033
+ code1 -= 257;
4034
+ code2 = lengthDecode[code1].bits;
4035
+ if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
4036
+ goto err;
4037
+ len = lengthDecode[code1].first + code2;
4038
+ if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
4039
+ goto err;
4040
+ code2 = distDecode[code1].bits;
4041
+ if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
4042
+ goto err;
4043
+ dist = distDecode[code1].first + code2;
4044
+ i = index;
4045
+ j = (index - dist) & flateMask;
4046
+ for (k = 0; k < len; ++k) {
4047
+ buf[i] = buf[j];
4048
+ i = (i + 1) & flateMask;
4049
+ j = (j + 1) & flateMask;
4050
+ }
4051
+ remain = len;
4052
+ }
4053
+
4054
+ } else {
4055
+ len = (blockLen < flateWindow) ? blockLen : flateWindow;
4056
+ for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
4057
+ if ((c = str->getChar()) == EOF) {
4058
+ endOfBlock = eof = gTrue;
4059
+ break;
4060
+ }
4061
+ buf[j] = c & 0xff;
4062
+ }
4063
+ remain = i;
4064
+ blockLen -= len;
4065
+ if (blockLen == 0)
4066
+ endOfBlock = gTrue;
4067
+ }
4068
+
4069
+ return;
4070
+
4071
+ err:
4072
+ error(getPos(), "Unexpected end of file in flate stream");
4073
+ endOfBlock = eof = gTrue;
4074
+ remain = 0;
4075
+ }
4076
+
4077
+ GBool FlateStream::startBlock() {
4078
+ int blockHdr;
4079
+ int c;
4080
+ int check;
4081
+
4082
+ // free the code tables from the previous block
4083
+ if (litCodeTab.codes != fixedLitCodeTab.codes) {
4084
+ gfree(litCodeTab.codes);
4085
+ }
4086
+ litCodeTab.codes = NULL;
4087
+ if (distCodeTab.codes != fixedDistCodeTab.codes) {
4088
+ gfree(distCodeTab.codes);
4089
+ }
4090
+ distCodeTab.codes = NULL;
4091
+
4092
+ // read block header
4093
+ blockHdr = getCodeWord(3);
4094
+ if (blockHdr & 1)
4095
+ eof = gTrue;
4096
+ blockHdr >>= 1;
4097
+
4098
+ // uncompressed block
4099
+ if (blockHdr == 0) {
4100
+ compressedBlock = gFalse;
4101
+ if ((c = str->getChar()) == EOF)
4102
+ goto err;
4103
+ blockLen = c & 0xff;
4104
+ if ((c = str->getChar()) == EOF)
4105
+ goto err;
4106
+ blockLen |= (c & 0xff) << 8;
4107
+ if ((c = str->getChar()) == EOF)
4108
+ goto err;
4109
+ check = c & 0xff;
4110
+ if ((c = str->getChar()) == EOF)
4111
+ goto err;
4112
+ check |= (c & 0xff) << 8;
4113
+ if (check != (~blockLen & 0xffff))
4114
+ error(getPos(), "Bad uncompressed block length in flate stream");
4115
+ codeBuf = 0;
4116
+ codeSize = 0;
4117
+
4118
+ // compressed block with fixed codes
4119
+ } else if (blockHdr == 1) {
4120
+ compressedBlock = gTrue;
4121
+ loadFixedCodes();
4122
+
4123
+ // compressed block with dynamic codes
4124
+ } else if (blockHdr == 2) {
4125
+ compressedBlock = gTrue;
4126
+ if (!readDynamicCodes()) {
4127
+ goto err;
4128
+ }
4129
+
4130
+ // unknown block type
4131
+ } else {
4132
+ goto err;
4133
+ }
4134
+
4135
+ endOfBlock = gFalse;
4136
+ return gTrue;
4137
+
4138
+ err:
4139
+ error(getPos(), "Bad block header in flate stream");
4140
+ endOfBlock = eof = gTrue;
4141
+ return gFalse;
4142
+ }
4143
+
4144
+ void FlateStream::loadFixedCodes() {
4145
+ litCodeTab.codes = fixedLitCodeTab.codes;
4146
+ litCodeTab.maxLen = fixedLitCodeTab.maxLen;
4147
+ distCodeTab.codes = fixedDistCodeTab.codes;
4148
+ distCodeTab.maxLen = fixedDistCodeTab.maxLen;
4149
+ }
4150
+
4151
+ GBool FlateStream::readDynamicCodes() {
4152
+ int numCodeLenCodes;
4153
+ int numLitCodes;
4154
+ int numDistCodes;
4155
+ int codeLenCodeLengths[flateMaxCodeLenCodes];
4156
+ FlateHuffmanTab codeLenCodeTab;
4157
+ int len, repeat, code;
4158
+ int i;
4159
+
4160
+ codeLenCodeTab.codes = NULL;
4161
+
4162
+ // read lengths
4163
+ if ((numLitCodes = getCodeWord(5)) == EOF) {
4164
+ goto err;
4165
+ }
4166
+ numLitCodes += 257;
4167
+ if ((numDistCodes = getCodeWord(5)) == EOF) {
4168
+ goto err;
4169
+ }
4170
+ numDistCodes += 1;
4171
+ if ((numCodeLenCodes = getCodeWord(4)) == EOF) {
4172
+ goto err;
4173
+ }
4174
+ numCodeLenCodes += 4;
4175
+ if (numLitCodes > flateMaxLitCodes ||
4176
+ numDistCodes > flateMaxDistCodes ||
4177
+ numCodeLenCodes > flateMaxCodeLenCodes) {
4178
+ goto err;
4179
+ }
4180
+
4181
+ // build the code length code table
4182
+ for (i = 0; i < flateMaxCodeLenCodes; ++i) {
4183
+ codeLenCodeLengths[i] = 0;
4184
+ }
4185
+ for (i = 0; i < numCodeLenCodes; ++i) {
4186
+ if ((codeLenCodeLengths[codeLenCodeMap[i]] = getCodeWord(3)) == -1) {
4187
+ goto err;
4188
+ }
4189
+ }
4190
+ compHuffmanCodes(codeLenCodeLengths, flateMaxCodeLenCodes, &codeLenCodeTab);
4191
+
4192
+ // build the literal and distance code tables
4193
+ len = 0;
4194
+ repeat = 0;
4195
+ i = 0;
4196
+ while (i < numLitCodes + numDistCodes) {
4197
+ if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) {
4198
+ goto err;
4199
+ }
4200
+ if (code == 16) {
4201
+ if ((repeat = getCodeWord(2)) == EOF) {
4202
+ goto err;
4203
+ }
4204
+ repeat += 3;
4205
+ if (i + repeat > numLitCodes + numDistCodes) {
4206
+ goto err;
4207
+ }
4208
+ for (; repeat > 0; --repeat) {
4209
+ codeLengths[i++] = len;
4210
+ }
4211
+ } else if (code == 17) {
4212
+ if ((repeat = getCodeWord(3)) == EOF) {
4213
+ goto err;
4214
+ }
4215
+ repeat += 3;
4216
+ if (i + repeat > numLitCodes + numDistCodes) {
4217
+ goto err;
4218
+ }
4219
+ len = 0;
4220
+ for (; repeat > 0; --repeat) {
4221
+ codeLengths[i++] = 0;
4222
+ }
4223
+ } else if (code == 18) {
4224
+ if ((repeat = getCodeWord(7)) == EOF) {
4225
+ goto err;
4226
+ }
4227
+ repeat += 11;
4228
+ if (i + repeat > numLitCodes + numDistCodes) {
4229
+ goto err;
4230
+ }
4231
+ len = 0;
4232
+ for (; repeat > 0; --repeat) {
4233
+ codeLengths[i++] = 0;
4234
+ }
4235
+ } else {
4236
+ codeLengths[i++] = len = code;
4237
+ }
4238
+ }
4239
+ compHuffmanCodes(codeLengths, numLitCodes, &litCodeTab);
4240
+ compHuffmanCodes(codeLengths + numLitCodes, numDistCodes, &distCodeTab);
4241
+
4242
+ gfree(codeLenCodeTab.codes);
4243
+ return gTrue;
4244
+
4245
+ err:
4246
+ error(getPos(), "Bad dynamic code table in flate stream");
4247
+ gfree(codeLenCodeTab.codes);
4248
+ return gFalse;
4249
+ }
4250
+
4251
+ // Convert an array <lengths> of <n> lengths, in value order, into a
4252
+ // Huffman code lookup table.
4253
+ void FlateStream::compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab) {
4254
+ int tabSize, len, code, code2, skip, val, i, t;
4255
+
4256
+ // find max code length
4257
+ tab->maxLen = 0;
4258
+ for (val = 0; val < n; ++val) {
4259
+ if (lengths[val] > tab->maxLen) {
4260
+ tab->maxLen = lengths[val];
4261
+ }
4262
+ }
4263
+
4264
+ // allocate the table
4265
+ tabSize = 1 << tab->maxLen;
4266
+ tab->codes = (FlateCode *)gmallocn(tabSize, sizeof(FlateCode));
4267
+
4268
+ // clear the table
4269
+ for (i = 0; i < tabSize; ++i) {
4270
+ tab->codes[i].len = 0;
4271
+ tab->codes[i].val = 0;
4272
+ }
4273
+
4274
+ // build the table
4275
+ for (len = 1, code = 0, skip = 2;
4276
+ len <= tab->maxLen;
4277
+ ++len, code <<= 1, skip <<= 1) {
4278
+ for (val = 0; val < n; ++val) {
4279
+ if (lengths[val] == len) {
4280
+
4281
+ // bit-reverse the code
4282
+ code2 = 0;
4283
+ t = code;
4284
+ for (i = 0; i < len; ++i) {
4285
+ code2 = (code2 << 1) | (t & 1);
4286
+ t >>= 1;
4287
+ }
4288
+
4289
+ // fill in the table entries
4290
+ for (i = code2; i < tabSize; i += skip) {
4291
+ tab->codes[i].len = (Gushort)len;
4292
+ tab->codes[i].val = (Gushort)val;
4293
+ }
4294
+
4295
+ ++code;
4296
+ }
4297
+ }
4298
+ }
4299
+ }
4300
+
4301
+ int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
4302
+ FlateCode *code;
4303
+ int c;
4304
+
4305
+ while (codeSize < tab->maxLen) {
4306
+ if ((c = str->getChar()) == EOF) {
4307
+ break;
4308
+ }
4309
+ codeBuf |= (c & 0xff) << codeSize;
4310
+ codeSize += 8;
4311
+ }
4312
+ code = &tab->codes[codeBuf & ((1 << tab->maxLen) - 1)];
4313
+ if (codeSize == 0 || codeSize < code->len || code->len == 0) {
4314
+ return EOF;
4315
+ }
4316
+ codeBuf >>= code->len;
4317
+ codeSize -= code->len;
4318
+ return (int)code->val;
4319
+ }
4320
+
4321
+ int FlateStream::getCodeWord(int bits) {
4322
+ int c;
4323
+
4324
+ while (codeSize < bits) {
4325
+ if ((c = str->getChar()) == EOF)
4326
+ return EOF;
4327
+ codeBuf |= (c & 0xff) << codeSize;
4328
+ codeSize += 8;
4329
+ }
4330
+ c = codeBuf & ((1 << bits) - 1);
4331
+ codeBuf >>= bits;
4332
+ codeSize -= bits;
4333
+ return c;
4334
+ }
4335
+
4336
+ //------------------------------------------------------------------------
4337
+ // EOFStream
4338
+ //------------------------------------------------------------------------
4339
+
4340
+ EOFStream::EOFStream(Stream *strA):
4341
+ FilterStream(strA) {
4342
+ }
4343
+
4344
+ EOFStream::~EOFStream() {
4345
+ delete str;
4346
+ }
4347
+
4348
+ //------------------------------------------------------------------------
4349
+ // FixedLengthEncoder
4350
+ //------------------------------------------------------------------------
4351
+
4352
+ FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA):
4353
+ FilterStream(strA) {
4354
+ length = lengthA;
4355
+ count = 0;
4356
+ }
4357
+
4358
+ FixedLengthEncoder::~FixedLengthEncoder() {
4359
+ if (str->isEncoder())
4360
+ delete str;
4361
+ }
4362
+
4363
+ void FixedLengthEncoder::reset() {
4364
+ str->reset();
4365
+ count = 0;
4366
+ }
4367
+
4368
+ int FixedLengthEncoder::getChar() {
4369
+ if (length >= 0 && count >= length)
4370
+ return EOF;
4371
+ ++count;
4372
+ return str->getChar();
4373
+ }
4374
+
4375
+ int FixedLengthEncoder::lookChar() {
4376
+ if (length >= 0 && count >= length)
4377
+ return EOF;
4378
+ return str->getChar();
4379
+ }
4380
+
4381
+ GBool FixedLengthEncoder::isBinary(GBool last) {
4382
+ return str->isBinary(gTrue);
4383
+ }
4384
+
4385
+ //------------------------------------------------------------------------
4386
+ // ASCIIHexEncoder
4387
+ //------------------------------------------------------------------------
4388
+
4389
+ ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA):
4390
+ FilterStream(strA) {
4391
+ bufPtr = bufEnd = buf;
4392
+ lineLen = 0;
4393
+ eof = gFalse;
4394
+ }
4395
+
4396
+ ASCIIHexEncoder::~ASCIIHexEncoder() {
4397
+ if (str->isEncoder()) {
4398
+ delete str;
4399
+ }
4400
+ }
4401
+
4402
+ void ASCIIHexEncoder::reset() {
4403
+ str->reset();
4404
+ bufPtr = bufEnd = buf;
4405
+ lineLen = 0;
4406
+ eof = gFalse;
4407
+ }
4408
+
4409
+ GBool ASCIIHexEncoder::fillBuf() {
4410
+ static char *hex = "0123456789abcdef";
4411
+ int c;
4412
+
4413
+ if (eof) {
4414
+ return gFalse;
4415
+ }
4416
+ bufPtr = bufEnd = buf;
4417
+ if ((c = str->getChar()) == EOF) {
4418
+ *bufEnd++ = '>';
4419
+ eof = gTrue;
4420
+ } else {
4421
+ if (lineLen >= 64) {
4422
+ *bufEnd++ = '\n';
4423
+ lineLen = 0;
4424
+ }
4425
+ *bufEnd++ = hex[(c >> 4) & 0x0f];
4426
+ *bufEnd++ = hex[c & 0x0f];
4427
+ lineLen += 2;
4428
+ }
4429
+ return gTrue;
4430
+ }
4431
+
4432
+ //------------------------------------------------------------------------
4433
+ // ASCII85Encoder
4434
+ //------------------------------------------------------------------------
4435
+
4436
+ ASCII85Encoder::ASCII85Encoder(Stream *strA):
4437
+ FilterStream(strA) {
4438
+ bufPtr = bufEnd = buf;
4439
+ lineLen = 0;
4440
+ eof = gFalse;
4441
+ }
4442
+
4443
+ ASCII85Encoder::~ASCII85Encoder() {
4444
+ if (str->isEncoder())
4445
+ delete str;
4446
+ }
4447
+
4448
+ void ASCII85Encoder::reset() {
4449
+ str->reset();
4450
+ bufPtr = bufEnd = buf;
4451
+ lineLen = 0;
4452
+ eof = gFalse;
4453
+ }
4454
+
4455
+ GBool ASCII85Encoder::fillBuf() {
4456
+ Gulong t;
4457
+ char buf1[5];
4458
+ int c0, c1, c2, c3;
4459
+ int n, i;
4460
+
4461
+ if (eof) {
4462
+ return gFalse;
4463
+ }
4464
+ c0 = str->getChar();
4465
+ c1 = str->getChar();
4466
+ c2 = str->getChar();
4467
+ c3 = str->getChar();
4468
+ bufPtr = bufEnd = buf;
4469
+ if (c3 == EOF) {
4470
+ if (c0 == EOF) {
4471
+ n = 0;
4472
+ t = 0;
4473
+ } else {
4474
+ if (c1 == EOF) {
4475
+ n = 1;
4476
+ t = c0 << 24;
4477
+ } else if (c2 == EOF) {
4478
+ n = 2;
4479
+ t = (c0 << 24) | (c1 << 16);
4480
+ } else {
4481
+ n = 3;
4482
+ t = (c0 << 24) | (c1 << 16) | (c2 << 8);
4483
+ }
4484
+ for (i = 4; i >= 0; --i) {
4485
+ buf1[i] = (char)(t % 85 + 0x21);
4486
+ t /= 85;
4487
+ }
4488
+ for (i = 0; i <= n; ++i) {
4489
+ *bufEnd++ = buf1[i];
4490
+ if (++lineLen == 65) {
4491
+ *bufEnd++ = '\n';
4492
+ lineLen = 0;
4493
+ }
4494
+ }
4495
+ }
4496
+ *bufEnd++ = '~';
4497
+ *bufEnd++ = '>';
4498
+ eof = gTrue;
4499
+ } else {
4500
+ t = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
4501
+ if (t == 0) {
4502
+ *bufEnd++ = 'z';
4503
+ if (++lineLen == 65) {
4504
+ *bufEnd++ = '\n';
4505
+ lineLen = 0;
4506
+ }
4507
+ } else {
4508
+ for (i = 4; i >= 0; --i) {
4509
+ buf1[i] = (char)(t % 85 + 0x21);
4510
+ t /= 85;
4511
+ }
4512
+ for (i = 0; i <= 4; ++i) {
4513
+ *bufEnd++ = buf1[i];
4514
+ if (++lineLen == 65) {
4515
+ *bufEnd++ = '\n';
4516
+ lineLen = 0;
4517
+ }
4518
+ }
4519
+ }
4520
+ }
4521
+ return gTrue;
4522
+ }
4523
+
4524
+ //------------------------------------------------------------------------
4525
+ // RunLengthEncoder
4526
+ //------------------------------------------------------------------------
4527
+
4528
+ RunLengthEncoder::RunLengthEncoder(Stream *strA):
4529
+ FilterStream(strA) {
4530
+ bufPtr = bufEnd = nextEnd = buf;
4531
+ eof = gFalse;
4532
+ }
4533
+
4534
+ RunLengthEncoder::~RunLengthEncoder() {
4535
+ if (str->isEncoder())
4536
+ delete str;
4537
+ }
4538
+
4539
+ void RunLengthEncoder::reset() {
4540
+ str->reset();
4541
+ bufPtr = bufEnd = nextEnd = buf;
4542
+ eof = gFalse;
4543
+ }
4544
+
4545
+ //
4546
+ // When fillBuf finishes, buf[] looks like this:
4547
+ // +-----+--------------+-----------------+--
4548
+ // + tag | ... data ... | next 0, 1, or 2 |
4549
+ // +-----+--------------+-----------------+--
4550
+ // ^ ^ ^
4551
+ // bufPtr bufEnd nextEnd
4552
+ //
4553
+ GBool RunLengthEncoder::fillBuf() {
4554
+ int c, c1, c2;
4555
+ int n;
4556
+
4557
+ // already hit EOF?
4558
+ if (eof)
4559
+ return gFalse;
4560
+
4561
+ // grab two bytes
4562
+ if (nextEnd < bufEnd + 1) {
4563
+ if ((c1 = str->getChar()) == EOF) {
4564
+ eof = gTrue;
4565
+ return gFalse;
4566
+ }
4567
+ } else {
4568
+ c1 = bufEnd[0] & 0xff;
4569
+ }
4570
+ if (nextEnd < bufEnd + 2) {
4571
+ if ((c2 = str->getChar()) == EOF) {
4572
+ eof = gTrue;
4573
+ buf[0] = 0;
4574
+ buf[1] = c1;
4575
+ bufPtr = buf;
4576
+ bufEnd = &buf[2];
4577
+ return gTrue;
4578
+ }
4579
+ } else {
4580
+ c2 = bufEnd[1] & 0xff;
4581
+ }
4582
+
4583
+ // check for repeat
4584
+ c = 0; // make gcc happy
4585
+ if (c1 == c2) {
4586
+ n = 2;
4587
+ while (n < 128 && (c = str->getChar()) == c1)
4588
+ ++n;
4589
+ buf[0] = (char)(257 - n);
4590
+ buf[1] = c1;
4591
+ bufEnd = &buf[2];
4592
+ if (c == EOF) {
4593
+ eof = gTrue;
4594
+ } else if (n < 128) {
4595
+ buf[2] = c;
4596
+ nextEnd = &buf[3];
4597
+ } else {
4598
+ nextEnd = bufEnd;
4599
+ }
4600
+
4601
+ // get up to 128 chars
4602
+ } else {
4603
+ buf[1] = c1;
4604
+ buf[2] = c2;
4605
+ n = 2;
4606
+ while (n < 128) {
4607
+ if ((c = str->getChar()) == EOF) {
4608
+ eof = gTrue;
4609
+ break;
4610
+ }
4611
+ ++n;
4612
+ buf[n] = c;
4613
+ if (buf[n] == buf[n-1])
4614
+ break;
4615
+ }
4616
+ if (buf[n] == buf[n-1]) {
4617
+ buf[0] = (char)(n-2-1);
4618
+ bufEnd = &buf[n-1];
4619
+ nextEnd = &buf[n+1];
4620
+ } else {
4621
+ buf[0] = (char)(n-1);
4622
+ bufEnd = nextEnd = &buf[n+1];
4623
+ }
4624
+ }
4625
+ bufPtr = buf;
4626
+ return gTrue;
4627
+ }