pdf2json 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }