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,145 @@
1
+ //========================================================================
2
+ //
3
+ // JBIG2Stream.h
4
+ //
5
+ // Copyright 2002-2003 Glyph & Cog, LLC
6
+ //
7
+ //========================================================================
8
+
9
+ #ifndef JBIG2STREAM_H
10
+ #define JBIG2STREAM_H
11
+
12
+ #include <aconf.h>
13
+
14
+ #ifdef USE_GCC_PRAGMAS
15
+ #pragma interface
16
+ #endif
17
+
18
+ #include "gtypes.h"
19
+ #include "Object.h"
20
+ #include "Stream.h"
21
+
22
+ class GList;
23
+ class JBIG2Segment;
24
+ class JBIG2Bitmap;
25
+ class JArithmeticDecoder;
26
+ class JArithmeticDecoderStats;
27
+ class JBIG2HuffmanDecoder;
28
+ struct JBIG2HuffmanTable;
29
+ class JBIG2MMRDecoder;
30
+
31
+ //------------------------------------------------------------------------
32
+
33
+ class JBIG2Stream: public FilterStream {
34
+ public:
35
+
36
+ JBIG2Stream(Stream *strA, Object *globalsStreamA);
37
+ virtual ~JBIG2Stream();
38
+ virtual StreamKind getKind() { return strJBIG2; }
39
+ virtual void reset();
40
+ virtual void close();
41
+ virtual int getChar();
42
+ virtual int lookChar();
43
+ virtual GString *getPSFilter(int psLevel, char *indent);
44
+ virtual GBool isBinary(GBool last = gTrue);
45
+
46
+ private:
47
+
48
+ void readSegments();
49
+ GBool readSymbolDictSeg(Guint segNum, Guint length,
50
+ Guint *refSegs, Guint nRefSegs);
51
+ void readTextRegionSeg(Guint segNum, GBool imm,
52
+ GBool lossless, Guint length,
53
+ Guint *refSegs, Guint nRefSegs);
54
+ JBIG2Bitmap *readTextRegion(GBool huff, GBool refine,
55
+ int w, int h,
56
+ Guint numInstances,
57
+ Guint logStrips,
58
+ int numSyms,
59
+ JBIG2HuffmanTable *symCodeTab,
60
+ Guint symCodeLen,
61
+ JBIG2Bitmap **syms,
62
+ Guint defPixel, Guint combOp,
63
+ Guint transposed, Guint refCorner,
64
+ int sOffset,
65
+ JBIG2HuffmanTable *huffFSTable,
66
+ JBIG2HuffmanTable *huffDSTable,
67
+ JBIG2HuffmanTable *huffDTTable,
68
+ JBIG2HuffmanTable *huffRDWTable,
69
+ JBIG2HuffmanTable *huffRDHTable,
70
+ JBIG2HuffmanTable *huffRDXTable,
71
+ JBIG2HuffmanTable *huffRDYTable,
72
+ JBIG2HuffmanTable *huffRSizeTable,
73
+ Guint templ,
74
+ int *atx, int *aty);
75
+ void readPatternDictSeg(Guint segNum, Guint length);
76
+ void readHalftoneRegionSeg(Guint segNum, GBool imm,
77
+ GBool lossless, Guint length,
78
+ Guint *refSegs, Guint nRefSegs);
79
+ void readGenericRegionSeg(Guint segNum, GBool imm,
80
+ GBool lossless, Guint length);
81
+ JBIG2Bitmap *readGenericBitmap(GBool mmr, int w, int h,
82
+ int templ, GBool tpgdOn,
83
+ GBool useSkip, JBIG2Bitmap *skip,
84
+ int *atx, int *aty,
85
+ int mmrDataLength);
86
+ void readGenericRefinementRegionSeg(Guint segNum, GBool imm,
87
+ GBool lossless, Guint length,
88
+ Guint *refSegs,
89
+ Guint nRefSegs);
90
+ JBIG2Bitmap *readGenericRefinementRegion(int w, int h,
91
+ int templ, GBool tpgrOn,
92
+ JBIG2Bitmap *refBitmap,
93
+ int refDX, int refDY,
94
+ int *atx, int *aty);
95
+ void readPageInfoSeg(Guint length);
96
+ void readEndOfStripeSeg(Guint length);
97
+ void readProfilesSeg(Guint length);
98
+ void readCodeTableSeg(Guint segNum, Guint length);
99
+ void readExtensionSeg(Guint length);
100
+ JBIG2Segment *findSegment(Guint segNum);
101
+ void discardSegment(Guint segNum);
102
+ void resetGenericStats(Guint templ,
103
+ JArithmeticDecoderStats *prevStats);
104
+ void resetRefinementStats(Guint templ,
105
+ JArithmeticDecoderStats *prevStats);
106
+ void resetIntStats(int symCodeLen);
107
+ GBool readUByte(Guint *x);
108
+ GBool readByte(int *x);
109
+ GBool readUWord(Guint *x);
110
+ GBool readULong(Guint *x);
111
+ GBool readLong(int *x);
112
+
113
+ Object globalsStream;
114
+ Guint pageW, pageH, curPageH;
115
+ Guint pageDefPixel;
116
+ JBIG2Bitmap *pageBitmap;
117
+ Guint defCombOp;
118
+ GList *segments; // [JBIG2Segment]
119
+ GList *globalSegments; // [JBIG2Segment]
120
+ Stream *curStr;
121
+ Guchar *dataPtr;
122
+ Guchar *dataEnd;
123
+
124
+ JArithmeticDecoder *arithDecoder;
125
+ JArithmeticDecoderStats *genericRegionStats;
126
+ JArithmeticDecoderStats *refinementRegionStats;
127
+ JArithmeticDecoderStats *iadhStats;
128
+ JArithmeticDecoderStats *iadwStats;
129
+ JArithmeticDecoderStats *iaexStats;
130
+ JArithmeticDecoderStats *iaaiStats;
131
+ JArithmeticDecoderStats *iadtStats;
132
+ JArithmeticDecoderStats *iaitStats;
133
+ JArithmeticDecoderStats *iafsStats;
134
+ JArithmeticDecoderStats *iadsStats;
135
+ JArithmeticDecoderStats *iardxStats;
136
+ JArithmeticDecoderStats *iardyStats;
137
+ JArithmeticDecoderStats *iardwStats;
138
+ JArithmeticDecoderStats *iardhStats;
139
+ JArithmeticDecoderStats *iariStats;
140
+ JArithmeticDecoderStats *iaidStats;
141
+ JBIG2HuffmanDecoder *huffDecoder;
142
+ JBIG2MMRDecoder *mmrDecoder;
143
+ };
144
+
145
+ #endif
@@ -0,0 +1,3144 @@
1
+ //========================================================================
2
+ //
3
+ // JPXStream.cc
4
+ //
5
+ // Copyright 2002-2003 Glyph & Cog, LLC
6
+ //
7
+ //========================================================================
8
+
9
+ #include <aconf.h>
10
+
11
+ #ifdef USE_GCC_PRAGMAS
12
+ #pragma implementation
13
+ #endif
14
+
15
+ #include <limits.h>
16
+ #include "gmem.h"
17
+ #include "Error.h"
18
+ #include "JArithmeticDecoder.h"
19
+ #include "JPXStream.h"
20
+
21
+ //~ to do:
22
+ // - precincts
23
+ // - ROI
24
+ // - progression order changes
25
+ // - packed packet headers
26
+ // - support for palettes, channel maps, etc.
27
+ // - make sure all needed JP2/JPX subboxes are parsed (readBoxes)
28
+ // - can we assume that QCC segments must come after the QCD segment?
29
+ // - skip EPH markers (readTilePartData)
30
+ // - handle tilePartToEOC in readTilePartData
31
+ // - deal with multiple codeword segments (readTilePartData,
32
+ // readCodeBlockData)
33
+ // - progression orders 2, 3, and 4
34
+ // - in coefficient decoding (readCodeBlockData):
35
+ // - termination pattern: terminate after every coding pass
36
+ // - error resilience segmentation symbol
37
+ // - selective arithmetic coding bypass
38
+ // - vertically causal context formation
39
+ // - coeffs longer than 31 bits (should just ignore the extra bits?)
40
+ // - handle boxes larger than 2^32 bytes
41
+ // - the fixed-point arithmetic won't handle 16-bit pixels
42
+
43
+ //------------------------------------------------------------------------
44
+
45
+ // number of contexts for the arithmetic decoder
46
+ #define jpxNContexts 19
47
+
48
+ #define jpxContextSigProp 0 // 0 - 8: significance prop and cleanup
49
+ #define jpxContextSign 9 // 9 - 13: sign
50
+ #define jpxContextMagRef 14 // 14 -16: magnitude refinement
51
+ #define jpxContextRunLength 17 // cleanup: run length
52
+ #define jpxContextUniform 18 // cleanup: first signif coeff
53
+
54
+ //------------------------------------------------------------------------
55
+
56
+ #define jpxPassSigProp 0
57
+ #define jpxPassMagRef 1
58
+ #define jpxPassCleanup 2
59
+
60
+ //------------------------------------------------------------------------
61
+
62
+ // arithmetic decoder context for the significance propagation and
63
+ // cleanup passes:
64
+ // [horiz][vert][diag][subband]
65
+ // where subband = 0 for HL
66
+ // = 1 for LH and LL
67
+ // = 2 for HH
68
+ static Guint sigPropContext[3][3][5][3] = {
69
+ {{{ 0, 0, 0 }, // horiz=0, vert=0, diag=0
70
+ { 1, 1, 3 }, // horiz=0, vert=0, diag=1
71
+ { 2, 2, 6 }, // horiz=0, vert=0, diag=2
72
+ { 2, 2, 8 }, // horiz=0, vert=0, diag=3
73
+ { 2, 2, 8 }}, // horiz=0, vert=0, diag=4
74
+ {{ 5, 3, 1 }, // horiz=0, vert=1, diag=0
75
+ { 6, 3, 4 }, // horiz=0, vert=1, diag=1
76
+ { 6, 3, 7 }, // horiz=0, vert=1, diag=2
77
+ { 6, 3, 8 }, // horiz=0, vert=1, diag=3
78
+ { 6, 3, 8 }}, // horiz=0, vert=1, diag=4
79
+ {{ 8, 4, 2 }, // horiz=0, vert=2, diag=0
80
+ { 8, 4, 5 }, // horiz=0, vert=2, diag=1
81
+ { 8, 4, 7 }, // horiz=0, vert=2, diag=2
82
+ { 8, 4, 8 }, // horiz=0, vert=2, diag=3
83
+ { 8, 4, 8 }}}, // horiz=0, vert=2, diag=4
84
+ {{{ 3, 5, 1 }, // horiz=1, vert=0, diag=0
85
+ { 3, 6, 4 }, // horiz=1, vert=0, diag=1
86
+ { 3, 6, 7 }, // horiz=1, vert=0, diag=2
87
+ { 3, 6, 8 }, // horiz=1, vert=0, diag=3
88
+ { 3, 6, 8 }}, // horiz=1, vert=0, diag=4
89
+ {{ 7, 7, 2 }, // horiz=1, vert=1, diag=0
90
+ { 7, 7, 5 }, // horiz=1, vert=1, diag=1
91
+ { 7, 7, 7 }, // horiz=1, vert=1, diag=2
92
+ { 7, 7, 8 }, // horiz=1, vert=1, diag=3
93
+ { 7, 7, 8 }}, // horiz=1, vert=1, diag=4
94
+ {{ 8, 7, 2 }, // horiz=1, vert=2, diag=0
95
+ { 8, 7, 5 }, // horiz=1, vert=2, diag=1
96
+ { 8, 7, 7 }, // horiz=1, vert=2, diag=2
97
+ { 8, 7, 8 }, // horiz=1, vert=2, diag=3
98
+ { 8, 7, 8 }}}, // horiz=1, vert=2, diag=4
99
+ {{{ 4, 8, 2 }, // horiz=2, vert=0, diag=0
100
+ { 4, 8, 5 }, // horiz=2, vert=0, diag=1
101
+ { 4, 8, 7 }, // horiz=2, vert=0, diag=2
102
+ { 4, 8, 8 }, // horiz=2, vert=0, diag=3
103
+ { 4, 8, 8 }}, // horiz=2, vert=0, diag=4
104
+ {{ 7, 8, 2 }, // horiz=2, vert=1, diag=0
105
+ { 7, 8, 5 }, // horiz=2, vert=1, diag=1
106
+ { 7, 8, 7 }, // horiz=2, vert=1, diag=2
107
+ { 7, 8, 8 }, // horiz=2, vert=1, diag=3
108
+ { 7, 8, 8 }}, // horiz=2, vert=1, diag=4
109
+ {{ 8, 8, 2 }, // horiz=2, vert=2, diag=0
110
+ { 8, 8, 5 }, // horiz=2, vert=2, diag=1
111
+ { 8, 8, 7 }, // horiz=2, vert=2, diag=2
112
+ { 8, 8, 8 }, // horiz=2, vert=2, diag=3
113
+ { 8, 8, 8 }}} // horiz=2, vert=2, diag=4
114
+ };
115
+
116
+ // arithmetic decoder context and xor bit for the sign bit in the
117
+ // significance propagation pass:
118
+ // [horiz][vert][k]
119
+ // where horiz/vert are offset by 2 (i.e., range is -2 .. 2)
120
+ // and k = 0 for the context
121
+ // = 1 for the xor bit
122
+ static Guint signContext[5][5][2] = {
123
+ {{ 13, 1 }, // horiz=-2, vert=-2
124
+ { 13, 1 }, // horiz=-2, vert=-1
125
+ { 12, 1 }, // horiz=-2, vert= 0
126
+ { 11, 1 }, // horiz=-2, vert=+1
127
+ { 11, 1 }}, // horiz=-2, vert=+2
128
+ {{ 13, 1 }, // horiz=-1, vert=-2
129
+ { 13, 1 }, // horiz=-1, vert=-1
130
+ { 12, 1 }, // horiz=-1, vert= 0
131
+ { 11, 1 }, // horiz=-1, vert=+1
132
+ { 11, 1 }}, // horiz=-1, vert=+2
133
+ {{ 10, 1 }, // horiz= 0, vert=-2
134
+ { 10, 1 }, // horiz= 0, vert=-1
135
+ { 9, 0 }, // horiz= 0, vert= 0
136
+ { 10, 0 }, // horiz= 0, vert=+1
137
+ { 10, 0 }}, // horiz= 0, vert=+2
138
+ {{ 11, 0 }, // horiz=+1, vert=-2
139
+ { 11, 0 }, // horiz=+1, vert=-1
140
+ { 12, 0 }, // horiz=+1, vert= 0
141
+ { 13, 0 }, // horiz=+1, vert=+1
142
+ { 13, 0 }}, // horiz=+1, vert=+2
143
+ {{ 11, 0 }, // horiz=+2, vert=-2
144
+ { 11, 0 }, // horiz=+2, vert=-1
145
+ { 12, 0 }, // horiz=+2, vert= 0
146
+ { 13, 0 }, // horiz=+2, vert=+1
147
+ { 13, 0 }}, // horiz=+2, vert=+2
148
+ };
149
+
150
+ //------------------------------------------------------------------------
151
+
152
+ // constants used in the IDWT
153
+ #define idwtAlpha -1.586134342059924
154
+ #define idwtBeta -0.052980118572961
155
+ #define idwtGamma 0.882911075530934
156
+ #define idwtDelta 0.443506852043971
157
+ #define idwtKappa 1.230174104914001
158
+ #define idwtIKappa (1.0 / idwtKappa)
159
+
160
+ // number of bits to the right of the decimal point for the fixed
161
+ // point arithmetic used in the IDWT
162
+ #define fracBits 16
163
+
164
+ //------------------------------------------------------------------------
165
+
166
+ // floor(x / y)
167
+ #define jpxFloorDiv(x, y) ((x) / (y))
168
+
169
+ // floor(x / 2^y)
170
+ #define jpxFloorDivPow2(x, y) ((x) >> (y))
171
+
172
+ // ceil(x / y)
173
+ #define jpxCeilDiv(x, y) (((x) + (y) - 1) / (y))
174
+
175
+ // ceil(x / 2^y)
176
+ #define jpxCeilDivPow2(x, y) (((x) + (1 << (y)) - 1) >> (y))
177
+
178
+ //------------------------------------------------------------------------
179
+
180
+ #if 1 //----- disable coverage tracking
181
+
182
+ #define cover(idx)
183
+
184
+ #else //----- enable coverage tracking
185
+
186
+ class JPXCover {
187
+ public:
188
+
189
+ JPXCover(int sizeA);
190
+ ~JPXCover();
191
+ void incr(int idx);
192
+
193
+ private:
194
+
195
+ int size, used;
196
+ int *data;
197
+ };
198
+
199
+ JPXCover::JPXCover(int sizeA) {
200
+ size = sizeA;
201
+ used = -1;
202
+ data = (int *)gmallocn(size, sizeof(int));
203
+ memset(data, 0, size * sizeof(int));
204
+ }
205
+
206
+ JPXCover::~JPXCover() {
207
+ int i;
208
+
209
+ printf("JPX coverage:\n");
210
+ for (i = 0; i <= used; ++i) {
211
+ printf(" %4d: %8d\n", i, data[i]);
212
+ }
213
+ gfree(data);
214
+ }
215
+
216
+ void JPXCover::incr(int idx) {
217
+ if (idx < size) {
218
+ ++data[idx];
219
+ if (idx > used) {
220
+ used = idx;
221
+ }
222
+ }
223
+ }
224
+
225
+ JPXCover jpxCover(150);
226
+
227
+ #define cover(idx) jpxCover.incr(idx)
228
+
229
+ #endif //----- coverage tracking
230
+
231
+ //------------------------------------------------------------------------
232
+
233
+ JPXStream::JPXStream(Stream *strA):
234
+ FilterStream(strA)
235
+ {
236
+ nComps = 0;
237
+ bpc = NULL;
238
+ width = height = 0;
239
+ haveCS = gFalse;
240
+ havePalette = gFalse;
241
+ haveCompMap = gFalse;
242
+ haveChannelDefn = gFalse;
243
+
244
+ img.tiles = NULL;
245
+ bitBuf = 0;
246
+ bitBufLen = 0;
247
+ bitBufSkip = gFalse;
248
+ byteCount = 0;
249
+ }
250
+
251
+ JPXStream::~JPXStream() {
252
+ close();
253
+ delete str;
254
+ }
255
+
256
+ void JPXStream::reset() {
257
+ str->reset();
258
+ if (readBoxes()) {
259
+ curY = img.yOffset;
260
+ } else {
261
+ // readBoxes reported an error, so we go immediately to EOF
262
+ curY = img.ySize;
263
+ }
264
+ curX = img.xOffset;
265
+ curComp = 0;
266
+ readBufLen = 0;
267
+ }
268
+
269
+ void JPXStream::close() {
270
+ JPXTile *tile;
271
+ JPXTileComp *tileComp;
272
+ JPXResLevel *resLevel;
273
+ JPXPrecinct *precinct;
274
+ JPXSubband *subband;
275
+ JPXCodeBlock *cb;
276
+ Guint comp, i, k, r, pre, sb;
277
+
278
+ gfree(bpc);
279
+ bpc = NULL;
280
+ if (havePalette) {
281
+ gfree(palette.bpc);
282
+ gfree(palette.c);
283
+ havePalette = gFalse;
284
+ }
285
+ if (haveCompMap) {
286
+ gfree(compMap.comp);
287
+ gfree(compMap.type);
288
+ gfree(compMap.pComp);
289
+ haveCompMap = gFalse;
290
+ }
291
+ if (haveChannelDefn) {
292
+ gfree(channelDefn.idx);
293
+ gfree(channelDefn.type);
294
+ gfree(channelDefn.assoc);
295
+ haveChannelDefn = gFalse;
296
+ }
297
+
298
+ if (img.tiles) {
299
+ for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
300
+ tile = &img.tiles[i];
301
+ if (tile->tileComps) {
302
+ for (comp = 0; comp < img.nComps; ++comp) {
303
+ tileComp = &tile->tileComps[comp];
304
+ gfree(tileComp->quantSteps);
305
+ gfree(tileComp->data);
306
+ gfree(tileComp->buf);
307
+ if (tileComp->resLevels) {
308
+ for (r = 0; r <= tileComp->nDecompLevels; ++r) {
309
+ resLevel = &tileComp->resLevels[r];
310
+ if (resLevel->precincts) {
311
+ for (pre = 0; pre < 1; ++pre) {
312
+ precinct = &resLevel->precincts[pre];
313
+ if (precinct->subbands) {
314
+ for (sb = 0; sb < (Guint)(r == 0 ? 1 : 3); ++sb) {
315
+ subband = &precinct->subbands[sb];
316
+ gfree(subband->inclusion);
317
+ gfree(subband->zeroBitPlane);
318
+ if (subband->cbs) {
319
+ for (k = 0; k < subband->nXCBs * subband->nYCBs; ++k) {
320
+ cb = &subband->cbs[k];
321
+ gfree(cb->coeffs);
322
+ if (cb->arithDecoder) {
323
+ delete cb->arithDecoder;
324
+ }
325
+ if (cb->stats) {
326
+ delete cb->stats;
327
+ }
328
+ }
329
+ gfree(subband->cbs);
330
+ }
331
+ }
332
+ gfree(precinct->subbands);
333
+ }
334
+ }
335
+ gfree(img.tiles[i].tileComps[comp].resLevels[r].precincts);
336
+ }
337
+ }
338
+ gfree(img.tiles[i].tileComps[comp].resLevels);
339
+ }
340
+ }
341
+ gfree(img.tiles[i].tileComps);
342
+ }
343
+ }
344
+ gfree(img.tiles);
345
+ img.tiles = NULL;
346
+ }
347
+ FilterStream::close();
348
+ }
349
+
350
+ int JPXStream::getChar() {
351
+ int c;
352
+
353
+ if (readBufLen < 8) {
354
+ fillReadBuf();
355
+ }
356
+ if (readBufLen == 8) {
357
+ c = readBuf & 0xff;
358
+ readBufLen = 0;
359
+ } else if (readBufLen > 8) {
360
+ c = (readBuf >> (readBufLen - 8)) & 0xff;
361
+ readBufLen -= 8;
362
+ } else if (readBufLen == 0) {
363
+ c = EOF;
364
+ } else {
365
+ c = (readBuf << (8 - readBufLen)) & 0xff;
366
+ readBufLen = 0;
367
+ }
368
+ return c;
369
+ }
370
+
371
+ int JPXStream::lookChar() {
372
+ int c;
373
+
374
+ if (readBufLen < 8) {
375
+ fillReadBuf();
376
+ }
377
+ if (readBufLen == 8) {
378
+ c = readBuf & 0xff;
379
+ } else if (readBufLen > 8) {
380
+ c = (readBuf >> (readBufLen - 8)) & 0xff;
381
+ } else if (readBufLen == 0) {
382
+ c = EOF;
383
+ } else {
384
+ c = (readBuf << (8 - readBufLen)) & 0xff;
385
+ }
386
+ return c;
387
+ }
388
+
389
+ void JPXStream::fillReadBuf() {
390
+ JPXTileComp *tileComp;
391
+ Guint tileIdx, tx, ty;
392
+ int pix, pixBits;
393
+
394
+ do {
395
+ if (curY >= img.ySize) {
396
+ return;
397
+ }
398
+ tileIdx = ((curY - img.yTileOffset) / img.yTileSize) * img.nXTiles
399
+ + (curX - img.xTileOffset) / img.xTileSize;
400
+ #if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
401
+ tileComp = &img.tiles[tileIdx].tileComps[curComp];
402
+ #else
403
+ tileComp = &img.tiles[tileIdx].tileComps[havePalette ? 0 : curComp];
404
+ #endif
405
+ tx = jpxCeilDiv((curX - img.xTileOffset) % img.xTileSize, tileComp->hSep);
406
+ ty = jpxCeilDiv((curY - img.yTileOffset) % img.yTileSize, tileComp->vSep);
407
+ pix = (int)tileComp->data[ty * (tileComp->x1 - tileComp->x0) + tx];
408
+ pixBits = tileComp->prec;
409
+ #if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
410
+ if (++curComp == img.nComps) {
411
+ #else
412
+ if (havePalette) {
413
+ if (pix >= 0 && pix < palette.nEntries) {
414
+ pix = palette.c[pix * palette.nComps + curComp];
415
+ } else {
416
+ pix =
417
+ pixBits = palette.bpc[curComp];
418
+ }
419
+ if (++curComp == (Guint)(havePalette ? palette.nComps : img.nComps)) {
420
+ #endif
421
+ curComp = 0;
422
+ if (++curX == img.xSize) {
423
+ curX = img.xOffset;
424
+ ++curY;
425
+ }
426
+ }
427
+ if (pixBits == 8) {
428
+ readBuf = (readBuf << 8) | (pix & 0xff);
429
+ } else {
430
+ readBuf = (readBuf << pixBits) | (pix & ((1 << pixBits) - 1));
431
+ }
432
+ readBufLen += pixBits;
433
+ } while (readBufLen < 8);
434
+ }
435
+
436
+ GString *JPXStream::getPSFilter(int psLevel, char *indent) {
437
+ return NULL;
438
+ }
439
+
440
+ GBool JPXStream::isBinary(GBool last) {
441
+ return str->isBinary(gTrue);
442
+ }
443
+
444
+ void JPXStream::getImageParams(int *bitsPerComponent,
445
+ StreamColorSpaceMode *csMode) {
446
+ Guint boxType, boxLen, dataLen, csEnum;
447
+ Guint bpc1, dummy, i;
448
+ int csMeth, csPrec, csPrec1, dummy2;
449
+ StreamColorSpaceMode csMode1;
450
+ GBool haveBPC, haveCSMode;
451
+
452
+ csPrec = 0; // make gcc happy
453
+ haveBPC = haveCSMode = gFalse;
454
+ str->reset();
455
+ if (str->lookChar() == 0xff) {
456
+ getImageParams2(bitsPerComponent, csMode);
457
+ } else {
458
+ while (readBoxHdr(&boxType, &boxLen, &dataLen)) {
459
+ if (boxType == 0x6a703268) { // JP2 header
460
+ cover(0);
461
+ // skip the superbox
462
+ } else if (boxType == 0x69686472) { // image header
463
+ cover(1);
464
+ if (readULong(&dummy) &&
465
+ readULong(&dummy) &&
466
+ readUWord(&dummy) &&
467
+ readUByte(&bpc1) &&
468
+ readUByte(&dummy) &&
469
+ readUByte(&dummy) &&
470
+ readUByte(&dummy)) {
471
+ *bitsPerComponent = bpc1 + 1;
472
+ haveBPC = gTrue;
473
+ }
474
+ } else if (boxType == 0x636F6C72) { // color specification
475
+ cover(2);
476
+ if (readByte(&csMeth) &&
477
+ readByte(&csPrec1) &&
478
+ readByte(&dummy2)) {
479
+ if (csMeth == 1) {
480
+ if (readULong(&csEnum)) {
481
+ csMode1 = streamCSNone;
482
+ if (csEnum == jpxCSBiLevel ||
483
+ csEnum == jpxCSGrayscale) {
484
+ csMode1 = streamCSDeviceGray;
485
+ } else if (csEnum == jpxCSCMYK) {
486
+ csMode1 = streamCSDeviceCMYK;
487
+ } else if (csEnum == jpxCSsRGB ||
488
+ csEnum == jpxCSCISesRGB ||
489
+ csEnum == jpxCSROMMRGB) {
490
+ csMode1 = streamCSDeviceRGB;
491
+ }
492
+ if (csMode1 != streamCSNone &&
493
+ (!haveCSMode || csPrec1 > csPrec)) {
494
+ *csMode = csMode1;
495
+ csPrec = csPrec1;
496
+ haveCSMode = gTrue;
497
+ }
498
+ for (i = 0; i < dataLen - 7; ++i) {
499
+ str->getChar();
500
+ }
501
+ }
502
+ } else {
503
+ for (i = 0; i < dataLen - 3; ++i) {
504
+ str->getChar();
505
+ }
506
+ }
507
+ }
508
+ } else if (boxType == 0x6A703263) { // codestream
509
+ cover(3);
510
+ if (!(haveBPC && haveCSMode)) {
511
+ getImageParams2(bitsPerComponent, csMode);
512
+ }
513
+ break;
514
+ } else {
515
+ cover(4);
516
+ for (i = 0; i < dataLen; ++i) {
517
+ str->getChar();
518
+ }
519
+ }
520
+ }
521
+ }
522
+ str->close();
523
+ }
524
+
525
+ // Get image parameters from the codestream.
526
+ void JPXStream::getImageParams2(int *bitsPerComponent,
527
+ StreamColorSpaceMode *csMode) {
528
+ int segType;
529
+ Guint segLen, nComps1, bpc1, dummy, i;
530
+
531
+ while (readMarkerHdr(&segType, &segLen)) {
532
+ if (segType == 0x51) { // SIZ - image and tile size
533
+ cover(5);
534
+ if (readUWord(&dummy) &&
535
+ readULong(&dummy) &&
536
+ readULong(&dummy) &&
537
+ readULong(&dummy) &&
538
+ readULong(&dummy) &&
539
+ readULong(&dummy) &&
540
+ readULong(&dummy) &&
541
+ readULong(&dummy) &&
542
+ readULong(&dummy) &&
543
+ readUWord(&nComps1) &&
544
+ readUByte(&bpc1)) {
545
+ *bitsPerComponent = (bpc1 & 0x7f) + 1;
546
+ // if there's no color space info, take a guess
547
+ if (nComps1 == 1) {
548
+ *csMode = streamCSDeviceGray;
549
+ } else if (nComps1 == 3) {
550
+ *csMode = streamCSDeviceRGB;
551
+ } else if (nComps1 == 4) {
552
+ *csMode = streamCSDeviceCMYK;
553
+ }
554
+ }
555
+ break;
556
+ } else {
557
+ cover(6);
558
+ if (segLen > 2) {
559
+ for (i = 0; i < segLen - 2; ++i) {
560
+ str->getChar();
561
+ }
562
+ }
563
+ }
564
+ }
565
+ }
566
+
567
+ GBool JPXStream::readBoxes() {
568
+ Guint boxType, boxLen, dataLen;
569
+ Guint bpc1, compression, unknownColorspace, ipr;
570
+ Guint i, j;
571
+
572
+ haveImgHdr = gFalse;
573
+
574
+ // check for a naked JPEG 2000 codestream (without the JP2/JPX
575
+ // wrapper) -- this appears to be a violation of the PDF spec, but
576
+ // Acrobat allows it
577
+ if (str->lookChar() == 0xff) {
578
+ cover(7);
579
+ error(getPos(), "Naked JPEG 2000 codestream, missing JP2/JPX wrapper");
580
+ readCodestream(0);
581
+ nComps = img.nComps;
582
+ bpc = (Guint *)gmallocn(nComps, sizeof(Guint));
583
+ for (i = 0; i < nComps; ++i) {
584
+ bpc[i] = img.tiles[0].tileComps[i].prec;
585
+ }
586
+ width = img.xSize - img.xOffset;
587
+ height = img.ySize - img.yOffset;
588
+ return gTrue;
589
+ }
590
+
591
+ while (readBoxHdr(&boxType, &boxLen, &dataLen)) {
592
+ switch (boxType) {
593
+ case 0x6a703268: // JP2 header
594
+ // this is a grouping box ('superbox') which has no real
595
+ // contents and doesn't appear to be used consistently, i.e.,
596
+ // some things which should be subboxes of the JP2 header box
597
+ // show up outside of it - so we simply ignore the JP2 header
598
+ // box
599
+ cover(8);
600
+ break;
601
+ case 0x69686472: // image header
602
+ cover(9);
603
+ if (!readULong(&height) ||
604
+ !readULong(&width) ||
605
+ !readUWord(&nComps) ||
606
+ !readUByte(&bpc1) ||
607
+ !readUByte(&compression) ||
608
+ !readUByte(&unknownColorspace) ||
609
+ !readUByte(&ipr)) {
610
+ error(getPos(), "Unexpected EOF in JPX stream");
611
+ return gFalse;
612
+ }
613
+ if (compression != 7) {
614
+ error(getPos(), "Unknown compression type in JPX stream");
615
+ return gFalse;
616
+ }
617
+ bpc = (Guint *)gmallocn(nComps, sizeof(Guint));
618
+ for (i = 0; i < nComps; ++i) {
619
+ bpc[i] = bpc1;
620
+ }
621
+ haveImgHdr = gTrue;
622
+ break;
623
+ case 0x62706363: // bits per component
624
+ cover(10);
625
+ if (!haveImgHdr) {
626
+ error(getPos(), "Found bits per component box before image header box in JPX stream");
627
+ return gFalse;
628
+ }
629
+ if (dataLen != nComps) {
630
+ error(getPos(), "Invalid bits per component box in JPX stream");
631
+ return gFalse;
632
+ }
633
+ for (i = 0; i < nComps; ++i) {
634
+ if (!readUByte(&bpc[i])) {
635
+ error(getPos(), "Unexpected EOF in JPX stream");
636
+ return gFalse;
637
+ }
638
+ }
639
+ break;
640
+ case 0x636F6C72: // color specification
641
+ cover(11);
642
+ if (!readColorSpecBox(dataLen)) {
643
+ return gFalse;
644
+ }
645
+ break;
646
+ case 0x70636c72: // palette
647
+ cover(12);
648
+ if (!readUWord(&palette.nEntries) ||
649
+ !readUByte(&palette.nComps)) {
650
+ error(getPos(), "Unexpected EOF in JPX stream");
651
+ return gFalse;
652
+ }
653
+ palette.bpc = (Guint *)gmallocn(palette.nComps, sizeof(Guint));
654
+ palette.c =
655
+ (int *)gmallocn(palette.nEntries * palette.nComps, sizeof(int));
656
+ for (i = 0; i < palette.nComps; ++i) {
657
+ if (!readUByte(&palette.bpc[i])) {
658
+ error(getPos(), "Unexpected EOF in JPX stream");
659
+ return gFalse;
660
+ }
661
+ ++palette.bpc[i];
662
+ }
663
+ for (i = 0; i < palette.nEntries; ++i) {
664
+ for (j = 0; j < palette.nComps; ++j) {
665
+ if (!readNBytes(((palette.bpc[j] & 0x7f) + 7) >> 3,
666
+ (palette.bpc[j] & 0x80) ? gTrue : gFalse,
667
+ &palette.c[i * palette.nComps + j])) {
668
+ error(getPos(), "Unexpected EOF in JPX stream");
669
+ return gFalse;
670
+ }
671
+ }
672
+ }
673
+ havePalette = gTrue;
674
+ break;
675
+ case 0x636d6170: // component mapping
676
+ cover(13);
677
+ compMap.nChannels = dataLen / 4;
678
+ compMap.comp = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint));
679
+ compMap.type = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint));
680
+ compMap.pComp = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint));
681
+ for (i = 0; i < compMap.nChannels; ++i) {
682
+ if (!readUWord(&compMap.comp[i]) ||
683
+ !readUByte(&compMap.type[i]) ||
684
+ !readUByte(&compMap.pComp[i])) {
685
+ error(getPos(), "Unexpected EOF in JPX stream");
686
+ return gFalse;
687
+ }
688
+ }
689
+ haveCompMap = gTrue;
690
+ break;
691
+ case 0x63646566: // channel definition
692
+ cover(14);
693
+ if (!readUWord(&channelDefn.nChannels)) {
694
+ error(getPos(), "Unexpected EOF in JPX stream");
695
+ return gFalse;
696
+ }
697
+ channelDefn.idx =
698
+ (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint));
699
+ channelDefn.type =
700
+ (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint));
701
+ channelDefn.assoc =
702
+ (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint));
703
+ for (i = 0; i < channelDefn.nChannels; ++i) {
704
+ if (!readUWord(&channelDefn.idx[i]) ||
705
+ !readUWord(&channelDefn.type[i]) ||
706
+ !readUWord(&channelDefn.assoc[i])) {
707
+ error(getPos(), "Unexpected EOF in JPX stream");
708
+ return gFalse;
709
+ }
710
+ }
711
+ haveChannelDefn = gTrue;
712
+ break;
713
+ case 0x6A703263: // contiguous codestream
714
+ cover(15);
715
+ if (!bpc) {
716
+ error(getPos(), "JPX stream is missing the image header box");
717
+ }
718
+ if (!haveCS) {
719
+ error(getPos(), "JPX stream has no supported color spec");
720
+ }
721
+ if (!readCodestream(dataLen)) {
722
+ return gFalse;
723
+ }
724
+ break;
725
+ default:
726
+ cover(16);
727
+ for (i = 0; i < dataLen; ++i) {
728
+ if (str->getChar() == EOF) {
729
+ error(getPos(), "Unexpected EOF in JPX stream");
730
+ return gFalse;
731
+ }
732
+ }
733
+ break;
734
+ }
735
+ }
736
+ return gTrue;
737
+ }
738
+
739
+ GBool JPXStream::readColorSpecBox(Guint dataLen) {
740
+ JPXColorSpec newCS;
741
+ Guint csApprox, csEnum;
742
+ Guint i;
743
+ GBool ok;
744
+
745
+ ok = gFalse;
746
+ if (!readUByte(&newCS.meth) ||
747
+ !readByte(&newCS.prec) ||
748
+ !readUByte(&csApprox)) {
749
+ goto err;
750
+ }
751
+ switch (newCS.meth) {
752
+ case 1: // enumerated colorspace
753
+ cover(17);
754
+ if (!readULong(&csEnum)) {
755
+ goto err;
756
+ }
757
+ newCS.enumerated.type = (JPXColorSpaceType)csEnum;
758
+ switch (newCS.enumerated.type) {
759
+ case jpxCSBiLevel:
760
+ ok = gTrue;
761
+ break;
762
+ case jpxCSYCbCr1:
763
+ ok = gTrue;
764
+ break;
765
+ case jpxCSYCbCr2:
766
+ ok = gTrue;
767
+ break;
768
+ case jpxCSYCBCr3:
769
+ ok = gTrue;
770
+ break;
771
+ case jpxCSPhotoYCC:
772
+ ok = gTrue;
773
+ break;
774
+ case jpxCSCMY:
775
+ ok = gTrue;
776
+ break;
777
+ case jpxCSCMYK:
778
+ ok = gTrue;
779
+ break;
780
+ case jpxCSYCCK:
781
+ ok = gTrue;
782
+ break;
783
+ case jpxCSCIELab:
784
+ if (dataLen == 7 + 7*4) {
785
+ if (!readULong(&newCS.enumerated.cieLab.rl) ||
786
+ !readULong(&newCS.enumerated.cieLab.ol) ||
787
+ !readULong(&newCS.enumerated.cieLab.ra) ||
788
+ !readULong(&newCS.enumerated.cieLab.oa) ||
789
+ !readULong(&newCS.enumerated.cieLab.rb) ||
790
+ !readULong(&newCS.enumerated.cieLab.ob) ||
791
+ !readULong(&newCS.enumerated.cieLab.il)) {
792
+ goto err;
793
+ }
794
+ } else if (dataLen == 7) {
795
+ //~ this assumes the 8-bit case
796
+ cover(92);
797
+ newCS.enumerated.cieLab.rl = 100;
798
+ newCS.enumerated.cieLab.ol = 0;
799
+ newCS.enumerated.cieLab.ra = 255;
800
+ newCS.enumerated.cieLab.oa = 128;
801
+ newCS.enumerated.cieLab.rb = 255;
802
+ newCS.enumerated.cieLab.ob = 96;
803
+ newCS.enumerated.cieLab.il = 0x00443530;
804
+ } else {
805
+ goto err;
806
+ }
807
+ ok = gTrue;
808
+ break;
809
+ case jpxCSsRGB:
810
+ ok = gTrue;
811
+ break;
812
+ case jpxCSGrayscale:
813
+ ok = gTrue;
814
+ break;
815
+ case jpxCSBiLevel2:
816
+ ok = gTrue;
817
+ break;
818
+ case jpxCSCIEJab:
819
+ // not allowed in PDF
820
+ goto err;
821
+ case jpxCSCISesRGB:
822
+ ok = gTrue;
823
+ break;
824
+ case jpxCSROMMRGB:
825
+ ok = gTrue;
826
+ break;
827
+ case jpxCSsRGBYCbCr:
828
+ ok = gTrue;
829
+ break;
830
+ case jpxCSYPbPr1125:
831
+ ok = gTrue;
832
+ break;
833
+ case jpxCSYPbPr1250:
834
+ ok = gTrue;
835
+ break;
836
+ default:
837
+ goto err;
838
+ }
839
+ break;
840
+ case 2: // restricted ICC profile
841
+ case 3: // any ICC profile (JPX)
842
+ case 4: // vendor color (JPX)
843
+ cover(18);
844
+ for (i = 0; i < dataLen - 3; ++i) {
845
+ if (str->getChar() == EOF) {
846
+ goto err;
847
+ }
848
+ }
849
+ break;
850
+ }
851
+
852
+ if (ok && (!haveCS || newCS.prec > cs.prec)) {
853
+ cs = newCS;
854
+ haveCS = gTrue;
855
+ }
856
+
857
+ return gTrue;
858
+
859
+ err:
860
+ error(getPos(), "Error in JPX color spec");
861
+ return gFalse;
862
+ }
863
+
864
+ GBool JPXStream::readCodestream(Guint len) {
865
+ JPXTile *tile;
866
+ JPXTileComp *tileComp;
867
+ int segType;
868
+ GBool haveSIZ, haveCOD, haveQCD, haveSOT;
869
+ Guint precinctSize, style;
870
+ Guint segLen, capabilities, comp, i, j, r;
871
+
872
+ //----- main header
873
+ haveSIZ = haveCOD = haveQCD = haveSOT = gFalse;
874
+ do {
875
+ if (!readMarkerHdr(&segType, &segLen)) {
876
+ error(getPos(), "Error in JPX codestream");
877
+ return gFalse;
878
+ }
879
+ switch (segType) {
880
+ case 0x4f: // SOC - start of codestream
881
+ // marker only
882
+ cover(19);
883
+ break;
884
+ case 0x51: // SIZ - image and tile size
885
+ cover(20);
886
+ if (!readUWord(&capabilities) ||
887
+ !readULong(&img.xSize) ||
888
+ !readULong(&img.ySize) ||
889
+ !readULong(&img.xOffset) ||
890
+ !readULong(&img.yOffset) ||
891
+ !readULong(&img.xTileSize) ||
892
+ !readULong(&img.yTileSize) ||
893
+ !readULong(&img.xTileOffset) ||
894
+ !readULong(&img.yTileOffset) ||
895
+ !readUWord(&img.nComps)) {
896
+ error(getPos(), "Error in JPX SIZ marker segment");
897
+ return gFalse;
898
+ }
899
+ if (haveImgHdr && img.nComps != nComps) {
900
+ error(getPos(), "Different number of components in JPX SIZ marker segment");
901
+ return gFalse;
902
+ }
903
+ img.nXTiles = (img.xSize - img.xTileOffset + img.xTileSize - 1)
904
+ / img.xTileSize;
905
+ img.nYTiles = (img.ySize - img.yTileOffset + img.yTileSize - 1)
906
+ / img.yTileSize;
907
+ // check for overflow before allocating memory
908
+ if (img.nXTiles <= 0 || img.nYTiles <= 0 ||
909
+ img.nXTiles >= INT_MAX / img.nYTiles) {
910
+ error(getPos(), "Bad tile count in JPX SIZ marker segment");
911
+ return gFalse;
912
+ }
913
+ img.tiles = (JPXTile *)gmallocn(img.nXTiles * img.nYTiles,
914
+ sizeof(JPXTile));
915
+ for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
916
+ img.tiles[i].tileComps = (JPXTileComp *)gmallocn(img.nComps,
917
+ sizeof(JPXTileComp));
918
+ for (comp = 0; comp < img.nComps; ++comp) {
919
+ img.tiles[i].tileComps[comp].quantSteps = NULL;
920
+ img.tiles[i].tileComps[comp].data = NULL;
921
+ img.tiles[i].tileComps[comp].buf = NULL;
922
+ img.tiles[i].tileComps[comp].resLevels = NULL;
923
+ }
924
+ }
925
+ for (comp = 0; comp < img.nComps; ++comp) {
926
+ if (!readUByte(&img.tiles[0].tileComps[comp].prec) ||
927
+ !readUByte(&img.tiles[0].tileComps[comp].hSep) ||
928
+ !readUByte(&img.tiles[0].tileComps[comp].vSep)) {
929
+ error(getPos(), "Error in JPX SIZ marker segment");
930
+ return gFalse;
931
+ }
932
+ img.tiles[0].tileComps[comp].sgned =
933
+ (img.tiles[0].tileComps[comp].prec & 0x80) ? gTrue : gFalse;
934
+ img.tiles[0].tileComps[comp].prec =
935
+ (img.tiles[0].tileComps[comp].prec & 0x7f) + 1;
936
+ for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
937
+ img.tiles[i].tileComps[comp] = img.tiles[0].tileComps[comp];
938
+ }
939
+ }
940
+ haveSIZ = gTrue;
941
+ break;
942
+ case 0x52: // COD - coding style default
943
+ cover(21);
944
+ if (!readUByte(&img.tiles[0].tileComps[0].style) ||
945
+ !readUByte(&img.tiles[0].progOrder) ||
946
+ !readUWord(&img.tiles[0].nLayers) ||
947
+ !readUByte(&img.tiles[0].multiComp) ||
948
+ !readUByte(&img.tiles[0].tileComps[0].nDecompLevels) ||
949
+ !readUByte(&img.tiles[0].tileComps[0].codeBlockW) ||
950
+ !readUByte(&img.tiles[0].tileComps[0].codeBlockH) ||
951
+ !readUByte(&img.tiles[0].tileComps[0].codeBlockStyle) ||
952
+ !readUByte(&img.tiles[0].tileComps[0].transform)) {
953
+ error(getPos(), "Error in JPX COD marker segment");
954
+ return gFalse;
955
+ }
956
+ img.tiles[0].tileComps[0].codeBlockW += 2;
957
+ img.tiles[0].tileComps[0].codeBlockH += 2;
958
+ for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
959
+ if (i != 0) {
960
+ img.tiles[i].progOrder = img.tiles[0].progOrder;
961
+ img.tiles[i].nLayers = img.tiles[0].nLayers;
962
+ img.tiles[i].multiComp = img.tiles[0].multiComp;
963
+ }
964
+ for (comp = 0; comp < img.nComps; ++comp) {
965
+ if (!(i == 0 && comp == 0)) {
966
+ img.tiles[i].tileComps[comp].style =
967
+ img.tiles[0].tileComps[0].style;
968
+ img.tiles[i].tileComps[comp].nDecompLevels =
969
+ img.tiles[0].tileComps[0].nDecompLevels;
970
+ img.tiles[i].tileComps[comp].codeBlockW =
971
+ img.tiles[0].tileComps[0].codeBlockW;
972
+ img.tiles[i].tileComps[comp].codeBlockH =
973
+ img.tiles[0].tileComps[0].codeBlockH;
974
+ img.tiles[i].tileComps[comp].codeBlockStyle =
975
+ img.tiles[0].tileComps[0].codeBlockStyle;
976
+ img.tiles[i].tileComps[comp].transform =
977
+ img.tiles[0].tileComps[0].transform;
978
+ }
979
+ img.tiles[i].tileComps[comp].resLevels =
980
+ (JPXResLevel *)gmallocn(
981
+ (img.tiles[i].tileComps[comp].nDecompLevels + 1),
982
+ sizeof(JPXResLevel));
983
+ for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
984
+ img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL;
985
+ }
986
+ }
987
+ }
988
+ for (r = 0; r <= img.tiles[0].tileComps[0].nDecompLevels; ++r) {
989
+ if (img.tiles[0].tileComps[0].style & 0x01) {
990
+ cover(91);
991
+ if (!readUByte(&precinctSize)) {
992
+ error(getPos(), "Error in JPX COD marker segment");
993
+ return gFalse;
994
+ }
995
+ img.tiles[0].tileComps[0].resLevels[r].precinctWidth =
996
+ precinctSize & 0x0f;
997
+ img.tiles[0].tileComps[0].resLevels[r].precinctHeight =
998
+ (precinctSize >> 4) & 0x0f;
999
+ } else {
1000
+ img.tiles[0].tileComps[0].resLevels[r].precinctWidth = 15;
1001
+ img.tiles[0].tileComps[0].resLevels[r].precinctHeight = 15;
1002
+ }
1003
+ }
1004
+ for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1005
+ for (comp = 0; comp < img.nComps; ++comp) {
1006
+ if (!(i == 0 && comp == 0)) {
1007
+ for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
1008
+ img.tiles[i].tileComps[comp].resLevels[r].precinctWidth =
1009
+ img.tiles[0].tileComps[0].resLevels[r].precinctWidth;
1010
+ img.tiles[i].tileComps[comp].resLevels[r].precinctHeight =
1011
+ img.tiles[0].tileComps[0].resLevels[r].precinctHeight;
1012
+ }
1013
+ }
1014
+ }
1015
+ }
1016
+ haveCOD = gTrue;
1017
+ break;
1018
+ case 0x53: // COC - coding style component
1019
+ cover(22);
1020
+ if (!haveCOD) {
1021
+ error(getPos(), "JPX COC marker segment before COD segment");
1022
+ return gFalse;
1023
+ }
1024
+ if ((img.nComps > 256 && !readUWord(&comp)) ||
1025
+ (img.nComps <= 256 && !readUByte(&comp)) ||
1026
+ comp >= img.nComps ||
1027
+ !readUByte(&style) ||
1028
+ !readUByte(&img.tiles[0].tileComps[comp].nDecompLevels) ||
1029
+ !readUByte(&img.tiles[0].tileComps[comp].codeBlockW) ||
1030
+ !readUByte(&img.tiles[0].tileComps[comp].codeBlockH) ||
1031
+ !readUByte(&img.tiles[0].tileComps[comp].codeBlockStyle) ||
1032
+ !readUByte(&img.tiles[0].tileComps[comp].transform)) {
1033
+ error(getPos(), "Error in JPX COC marker segment");
1034
+ return gFalse;
1035
+ }
1036
+ img.tiles[0].tileComps[comp].style =
1037
+ (img.tiles[0].tileComps[comp].style & ~1) | (style & 1);
1038
+ img.tiles[0].tileComps[comp].codeBlockW += 2;
1039
+ img.tiles[0].tileComps[comp].codeBlockH += 2;
1040
+ for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1041
+ if (i != 0) {
1042
+ img.tiles[i].tileComps[comp].style =
1043
+ img.tiles[0].tileComps[comp].style;
1044
+ img.tiles[i].tileComps[comp].nDecompLevels =
1045
+ img.tiles[0].tileComps[comp].nDecompLevels;
1046
+ img.tiles[i].tileComps[comp].codeBlockW =
1047
+ img.tiles[0].tileComps[comp].codeBlockW;
1048
+ img.tiles[i].tileComps[comp].codeBlockH =
1049
+ img.tiles[0].tileComps[comp].codeBlockH;
1050
+ img.tiles[i].tileComps[comp].codeBlockStyle =
1051
+ img.tiles[0].tileComps[comp].codeBlockStyle;
1052
+ img.tiles[i].tileComps[comp].transform =
1053
+ img.tiles[0].tileComps[comp].transform;
1054
+ }
1055
+ img.tiles[i].tileComps[comp].resLevels =
1056
+ (JPXResLevel *)greallocn(
1057
+ img.tiles[i].tileComps[comp].resLevels,
1058
+ (img.tiles[i].tileComps[comp].nDecompLevels + 1),
1059
+ sizeof(JPXResLevel));
1060
+ for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
1061
+ img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL;
1062
+ }
1063
+ }
1064
+ for (r = 0; r <= img.tiles[0].tileComps[comp].nDecompLevels; ++r) {
1065
+ if (img.tiles[0].tileComps[comp].style & 0x01) {
1066
+ if (!readUByte(&precinctSize)) {
1067
+ error(getPos(), "Error in JPX COD marker segment");
1068
+ return gFalse;
1069
+ }
1070
+ img.tiles[0].tileComps[comp].resLevels[r].precinctWidth =
1071
+ precinctSize & 0x0f;
1072
+ img.tiles[0].tileComps[comp].resLevels[r].precinctHeight =
1073
+ (precinctSize >> 4) & 0x0f;
1074
+ } else {
1075
+ img.tiles[0].tileComps[comp].resLevels[r].precinctWidth = 15;
1076
+ img.tiles[0].tileComps[comp].resLevels[r].precinctHeight = 15;
1077
+ }
1078
+ }
1079
+ for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
1080
+ for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
1081
+ img.tiles[i].tileComps[comp].resLevels[r].precinctWidth =
1082
+ img.tiles[0].tileComps[comp].resLevels[r].precinctWidth;
1083
+ img.tiles[i].tileComps[comp].resLevels[r].precinctHeight =
1084
+ img.tiles[0].tileComps[comp].resLevels[r].precinctHeight;
1085
+ }
1086
+ }
1087
+ break;
1088
+ case 0x5c: // QCD - quantization default
1089
+ cover(23);
1090
+ if (!readUByte(&img.tiles[0].tileComps[0].quantStyle)) {
1091
+ error(getPos(), "Error in JPX QCD marker segment");
1092
+ return gFalse;
1093
+ }
1094
+ if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x00) {
1095
+ img.tiles[0].tileComps[0].nQuantSteps = segLen - 3;
1096
+ img.tiles[0].tileComps[0].quantSteps =
1097
+ (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps,
1098
+ img.tiles[0].tileComps[0].nQuantSteps,
1099
+ sizeof(Guint));
1100
+ for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) {
1101
+ if (!readUByte(&img.tiles[0].tileComps[0].quantSteps[i])) {
1102
+ error(getPos(), "Error in JPX QCD marker segment");
1103
+ return gFalse;
1104
+ }
1105
+ }
1106
+ } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x01) {
1107
+ img.tiles[0].tileComps[0].nQuantSteps = 1;
1108
+ img.tiles[0].tileComps[0].quantSteps =
1109
+ (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps,
1110
+ img.tiles[0].tileComps[0].nQuantSteps,
1111
+ sizeof(Guint));
1112
+ if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[0])) {
1113
+ error(getPos(), "Error in JPX QCD marker segment");
1114
+ return gFalse;
1115
+ }
1116
+ } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x02) {
1117
+ img.tiles[0].tileComps[0].nQuantSteps = (segLen - 3) / 2;
1118
+ img.tiles[0].tileComps[0].quantSteps =
1119
+ (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps,
1120
+ img.tiles[0].tileComps[0].nQuantSteps,
1121
+ sizeof(Guint));
1122
+ for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) {
1123
+ if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[i])) {
1124
+ error(getPos(), "Error in JPX QCD marker segment");
1125
+ return gFalse;
1126
+ }
1127
+ }
1128
+ } else {
1129
+ error(getPos(), "Error in JPX QCD marker segment");
1130
+ return gFalse;
1131
+ }
1132
+ for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1133
+ for (comp = 0; comp < img.nComps; ++comp) {
1134
+ if (!(i == 0 && comp == 0)) {
1135
+ img.tiles[i].tileComps[comp].quantStyle =
1136
+ img.tiles[0].tileComps[0].quantStyle;
1137
+ img.tiles[i].tileComps[comp].nQuantSteps =
1138
+ img.tiles[0].tileComps[0].nQuantSteps;
1139
+ img.tiles[i].tileComps[comp].quantSteps =
1140
+ (Guint *)greallocn(img.tiles[i].tileComps[comp].quantSteps,
1141
+ img.tiles[0].tileComps[0].nQuantSteps,
1142
+ sizeof(Guint));
1143
+ for (j = 0; j < img.tiles[0].tileComps[0].nQuantSteps; ++j) {
1144
+ img.tiles[i].tileComps[comp].quantSteps[j] =
1145
+ img.tiles[0].tileComps[0].quantSteps[j];
1146
+ }
1147
+ }
1148
+ }
1149
+ }
1150
+ haveQCD = gTrue;
1151
+ break;
1152
+ case 0x5d: // QCC - quantization component
1153
+ cover(24);
1154
+ if (!haveQCD) {
1155
+ error(getPos(), "JPX QCC marker segment before QCD segment");
1156
+ return gFalse;
1157
+ }
1158
+ if ((img.nComps > 256 && !readUWord(&comp)) ||
1159
+ (img.nComps <= 256 && !readUByte(&comp)) ||
1160
+ comp >= img.nComps ||
1161
+ !readUByte(&img.tiles[0].tileComps[comp].quantStyle)) {
1162
+ error(getPos(), "Error in JPX QCC marker segment");
1163
+ return gFalse;
1164
+ }
1165
+ if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x00) {
1166
+ img.tiles[0].tileComps[comp].nQuantSteps =
1167
+ segLen - (img.nComps > 256 ? 5 : 4);
1168
+ img.tiles[0].tileComps[comp].quantSteps =
1169
+ (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps,
1170
+ img.tiles[0].tileComps[comp].nQuantSteps,
1171
+ sizeof(Guint));
1172
+ for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) {
1173
+ if (!readUByte(&img.tiles[0].tileComps[comp].quantSteps[i])) {
1174
+ error(getPos(), "Error in JPX QCC marker segment");
1175
+ return gFalse;
1176
+ }
1177
+ }
1178
+ } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x01) {
1179
+ img.tiles[0].tileComps[comp].nQuantSteps = 1;
1180
+ img.tiles[0].tileComps[comp].quantSteps =
1181
+ (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps,
1182
+ img.tiles[0].tileComps[comp].nQuantSteps,
1183
+ sizeof(Guint));
1184
+ if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[0])) {
1185
+ error(getPos(), "Error in JPX QCC marker segment");
1186
+ return gFalse;
1187
+ }
1188
+ } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x02) {
1189
+ img.tiles[0].tileComps[comp].nQuantSteps =
1190
+ (segLen - (img.nComps > 256 ? 5 : 4)) / 2;
1191
+ img.tiles[0].tileComps[comp].quantSteps =
1192
+ (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps,
1193
+ img.tiles[0].tileComps[comp].nQuantSteps,
1194
+ sizeof(Guint));
1195
+ for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) {
1196
+ if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[i])) {
1197
+ error(getPos(), "Error in JPX QCD marker segment");
1198
+ return gFalse;
1199
+ }
1200
+ }
1201
+ } else {
1202
+ error(getPos(), "Error in JPX QCC marker segment");
1203
+ return gFalse;
1204
+ }
1205
+ for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
1206
+ img.tiles[i].tileComps[comp].quantStyle =
1207
+ img.tiles[0].tileComps[comp].quantStyle;
1208
+ img.tiles[i].tileComps[comp].nQuantSteps =
1209
+ img.tiles[0].tileComps[comp].nQuantSteps;
1210
+ img.tiles[i].tileComps[comp].quantSteps =
1211
+ (Guint *)greallocn(img.tiles[i].tileComps[comp].quantSteps,
1212
+ img.tiles[0].tileComps[comp].nQuantSteps,
1213
+ sizeof(Guint));
1214
+ for (j = 0; j < img.tiles[0].tileComps[comp].nQuantSteps; ++j) {
1215
+ img.tiles[i].tileComps[comp].quantSteps[j] =
1216
+ img.tiles[0].tileComps[comp].quantSteps[j];
1217
+ }
1218
+ }
1219
+ break;
1220
+ case 0x5e: // RGN - region of interest
1221
+ cover(25);
1222
+ #if 1 //~ ROI is unimplemented
1223
+ fprintf(stderr, "RGN\n");
1224
+ for (i = 0; i < segLen - 2; ++i) {
1225
+ if (str->getChar() == EOF) {
1226
+ error(getPos(), "Error in JPX PPM marker segment");
1227
+ return gFalse;
1228
+ }
1229
+ }
1230
+ #else
1231
+ if ((img.nComps > 256 && !readUWord(&comp)) ||
1232
+ (img.nComps <= 256 && !readUByte(&comp)) ||
1233
+ comp >= img.nComps ||
1234
+ !readUByte(&compInfo[comp].defROI.style) ||
1235
+ !readUByte(&compInfo[comp].defROI.shift)) {
1236
+ error(getPos(), "Error in JPX RGN marker segment");
1237
+ return gFalse;
1238
+ }
1239
+ #endif
1240
+ break;
1241
+ case 0x5f: // POC - progression order change
1242
+ cover(26);
1243
+ #if 1 //~ progression order changes are unimplemented
1244
+ fprintf(stderr, "POC\n");
1245
+ for (i = 0; i < segLen - 2; ++i) {
1246
+ if (str->getChar() == EOF) {
1247
+ error(getPos(), "Error in JPX PPM marker segment");
1248
+ return gFalse;
1249
+ }
1250
+ }
1251
+ #else
1252
+ nProgs = (segLen - 2) / (img.nComps > 256 ? 9 : 7);
1253
+ progs = (JPXProgOrder *)gmallocn(nProgs, sizeof(JPXProgOrder));
1254
+ for (i = 0; i < nProgs; ++i) {
1255
+ if (!readUByte(&progs[i].startRes) ||
1256
+ !(img.nComps > 256 && readUWord(&progs[i].startComp)) ||
1257
+ !(img.nComps <= 256 && readUByte(&progs[i].startComp)) ||
1258
+ !readUWord(&progs[i].endLayer) ||
1259
+ !readUByte(&progs[i].endRes) ||
1260
+ !(img.nComps > 256 && readUWord(&progs[i].endComp)) ||
1261
+ !(img.nComps <= 256 && readUByte(&progs[i].endComp)) ||
1262
+ !readUByte(&progs[i].progOrder)) {
1263
+ error(getPos(), "Error in JPX POC marker segment");
1264
+ return gFalse;
1265
+ }
1266
+ }
1267
+ #endif
1268
+ break;
1269
+ case 0x60: // PPM - packed packet headers, main header
1270
+ cover(27);
1271
+ #if 1 //~ packed packet headers are unimplemented
1272
+ fprintf(stderr, "PPM\n");
1273
+ for (i = 0; i < segLen - 2; ++i) {
1274
+ if (str->getChar() == EOF) {
1275
+ error(getPos(), "Error in JPX PPM marker segment");
1276
+ return gFalse;
1277
+ }
1278
+ }
1279
+ #endif
1280
+ break;
1281
+ case 0x55: // TLM - tile-part lengths
1282
+ // skipped
1283
+ cover(28);
1284
+ for (i = 0; i < segLen - 2; ++i) {
1285
+ if (str->getChar() == EOF) {
1286
+ error(getPos(), "Error in JPX TLM marker segment");
1287
+ return gFalse;
1288
+ }
1289
+ }
1290
+ break;
1291
+ case 0x57: // PLM - packet length, main header
1292
+ // skipped
1293
+ cover(29);
1294
+ for (i = 0; i < segLen - 2; ++i) {
1295
+ if (str->getChar() == EOF) {
1296
+ error(getPos(), "Error in JPX PLM marker segment");
1297
+ return gFalse;
1298
+ }
1299
+ }
1300
+ break;
1301
+ case 0x63: // CRG - component registration
1302
+ // skipped
1303
+ cover(30);
1304
+ for (i = 0; i < segLen - 2; ++i) {
1305
+ if (str->getChar() == EOF) {
1306
+ error(getPos(), "Error in JPX CRG marker segment");
1307
+ return gFalse;
1308
+ }
1309
+ }
1310
+ break;
1311
+ case 0x64: // COM - comment
1312
+ // skipped
1313
+ cover(31);
1314
+ for (i = 0; i < segLen - 2; ++i) {
1315
+ if (str->getChar() == EOF) {
1316
+ error(getPos(), "Error in JPX COM marker segment");
1317
+ return gFalse;
1318
+ }
1319
+ }
1320
+ break;
1321
+ case 0x90: // SOT - start of tile
1322
+ cover(32);
1323
+ haveSOT = gTrue;
1324
+ break;
1325
+ default:
1326
+ cover(33);
1327
+ error(getPos(), "Unknown marker segment %02x in JPX stream", segType);
1328
+ for (i = 0; i < segLen - 2; ++i) {
1329
+ if (str->getChar() == EOF) {
1330
+ break;
1331
+ }
1332
+ }
1333
+ break;
1334
+ }
1335
+ } while (!haveSOT);
1336
+
1337
+ if (!haveSIZ) {
1338
+ error(getPos(), "Missing SIZ marker segment in JPX stream");
1339
+ return gFalse;
1340
+ }
1341
+ if (!haveCOD) {
1342
+ error(getPos(), "Missing COD marker segment in JPX stream");
1343
+ return gFalse;
1344
+ }
1345
+ if (!haveQCD) {
1346
+ error(getPos(), "Missing QCD marker segment in JPX stream");
1347
+ return gFalse;
1348
+ }
1349
+
1350
+ //----- read the tile-parts
1351
+ while (1) {
1352
+ if (!readTilePart()) {
1353
+ return gFalse;
1354
+ }
1355
+ if (!readMarkerHdr(&segType, &segLen)) {
1356
+ error(getPos(), "Error in JPX codestream");
1357
+ return gFalse;
1358
+ }
1359
+ if (segType != 0x90) { // SOT - start of tile
1360
+ break;
1361
+ }
1362
+ }
1363
+
1364
+ if (segType != 0xd9) { // EOC - end of codestream
1365
+ error(getPos(), "Missing EOC marker in JPX codestream");
1366
+ return gFalse;
1367
+ }
1368
+
1369
+ //----- finish decoding the image
1370
+ for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1371
+ tile = &img.tiles[i];
1372
+ for (comp = 0; comp < img.nComps; ++comp) {
1373
+ tileComp = &tile->tileComps[comp];
1374
+ inverseTransform(tileComp);
1375
+ }
1376
+ if (!inverseMultiCompAndDC(tile)) {
1377
+ return gFalse;
1378
+ }
1379
+ }
1380
+
1381
+ //~ can free memory below tileComps here, and also tileComp.buf
1382
+
1383
+ return gTrue;
1384
+ }
1385
+
1386
+ GBool JPXStream::readTilePart() {
1387
+ JPXTile *tile;
1388
+ JPXTileComp *tileComp;
1389
+ JPXResLevel *resLevel;
1390
+ JPXPrecinct *precinct;
1391
+ JPXSubband *subband;
1392
+ JPXCodeBlock *cb;
1393
+ GBool haveSOD;
1394
+ Guint tileIdx, tilePartLen, tilePartIdx, nTileParts;
1395
+ GBool tilePartToEOC;
1396
+ Guint precinctSize, style;
1397
+ Guint n, nSBs, nx, ny, sbx0, sby0, comp, segLen;
1398
+ Guint i, j, k, cbX, cbY, r, pre, sb, cbi;
1399
+ int segType, level;
1400
+
1401
+ // process the SOT marker segment
1402
+ if (!readUWord(&tileIdx) ||
1403
+ !readULong(&tilePartLen) ||
1404
+ !readUByte(&tilePartIdx) ||
1405
+ !readUByte(&nTileParts)) {
1406
+ error(getPos(), "Error in JPX SOT marker segment");
1407
+ return gFalse;
1408
+ }
1409
+
1410
+ if (tileIdx >= img.nXTiles * img.nYTiles) {
1411
+ error(getPos(), "Weird tile index in JPX stream");
1412
+ return gFalse;
1413
+ }
1414
+
1415
+ tilePartToEOC = tilePartLen == 0;
1416
+ tilePartLen -= 12; // subtract size of SOT segment
1417
+
1418
+ haveSOD = gFalse;
1419
+ do {
1420
+ if (!readMarkerHdr(&segType, &segLen)) {
1421
+ error(getPos(), "Error in JPX tile-part codestream");
1422
+ return gFalse;
1423
+ }
1424
+ tilePartLen -= 2 + segLen;
1425
+ switch (segType) {
1426
+ case 0x52: // COD - coding style default
1427
+ cover(34);
1428
+ if (!readUByte(&img.tiles[tileIdx].tileComps[0].style) ||
1429
+ !readUByte(&img.tiles[tileIdx].progOrder) ||
1430
+ !readUWord(&img.tiles[tileIdx].nLayers) ||
1431
+ !readUByte(&img.tiles[tileIdx].multiComp) ||
1432
+ !readUByte(&img.tiles[tileIdx].tileComps[0].nDecompLevels) ||
1433
+ !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockW) ||
1434
+ !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockH) ||
1435
+ !readUByte(&img.tiles[tileIdx].tileComps[0].codeBlockStyle) ||
1436
+ !readUByte(&img.tiles[tileIdx].tileComps[0].transform)) {
1437
+ error(getPos(), "Error in JPX COD marker segment");
1438
+ return gFalse;
1439
+ }
1440
+ img.tiles[tileIdx].tileComps[0].codeBlockW += 2;
1441
+ img.tiles[tileIdx].tileComps[0].codeBlockH += 2;
1442
+ for (comp = 0; comp < img.nComps; ++comp) {
1443
+ if (comp != 0) {
1444
+ img.tiles[tileIdx].tileComps[comp].style =
1445
+ img.tiles[tileIdx].tileComps[0].style;
1446
+ img.tiles[tileIdx].tileComps[comp].nDecompLevels =
1447
+ img.tiles[tileIdx].tileComps[0].nDecompLevels;
1448
+ img.tiles[tileIdx].tileComps[comp].codeBlockW =
1449
+ img.tiles[tileIdx].tileComps[0].codeBlockW;
1450
+ img.tiles[tileIdx].tileComps[comp].codeBlockH =
1451
+ img.tiles[tileIdx].tileComps[0].codeBlockH;
1452
+ img.tiles[tileIdx].tileComps[comp].codeBlockStyle =
1453
+ img.tiles[tileIdx].tileComps[0].codeBlockStyle;
1454
+ img.tiles[tileIdx].tileComps[comp].transform =
1455
+ img.tiles[tileIdx].tileComps[0].transform;
1456
+ }
1457
+ img.tiles[tileIdx].tileComps[comp].resLevels =
1458
+ (JPXResLevel *)greallocn(
1459
+ img.tiles[tileIdx].tileComps[comp].resLevels,
1460
+ (img.tiles[tileIdx].tileComps[comp].nDecompLevels + 1),
1461
+ sizeof(JPXResLevel));
1462
+ for (r = 0;
1463
+ r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels;
1464
+ ++r) {
1465
+ img.tiles[tileIdx].tileComps[comp].resLevels[r].precincts = NULL;
1466
+ }
1467
+ }
1468
+ for (r = 0; r <= img.tiles[tileIdx].tileComps[0].nDecompLevels; ++r) {
1469
+ if (img.tiles[tileIdx].tileComps[0].style & 0x01) {
1470
+ if (!readUByte(&precinctSize)) {
1471
+ error(getPos(), "Error in JPX COD marker segment");
1472
+ return gFalse;
1473
+ }
1474
+ img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth =
1475
+ precinctSize & 0x0f;
1476
+ img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight =
1477
+ (precinctSize >> 4) & 0x0f;
1478
+ } else {
1479
+ img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth = 15;
1480
+ img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight = 15;
1481
+ }
1482
+ }
1483
+ for (comp = 1; comp < img.nComps; ++comp) {
1484
+ for (r = 0;
1485
+ r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels;
1486
+ ++r) {
1487
+ img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth =
1488
+ img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth;
1489
+ img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight =
1490
+ img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight;
1491
+ }
1492
+ }
1493
+ break;
1494
+ case 0x53: // COC - coding style component
1495
+ cover(35);
1496
+ if ((img.nComps > 256 && !readUWord(&comp)) ||
1497
+ (img.nComps <= 256 && !readUByte(&comp)) ||
1498
+ comp >= img.nComps ||
1499
+ !readUByte(&style) ||
1500
+ !readUByte(&img.tiles[tileIdx].tileComps[comp].nDecompLevels) ||
1501
+ !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockW) ||
1502
+ !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockH) ||
1503
+ !readUByte(&img.tiles[tileIdx].tileComps[comp].codeBlockStyle) ||
1504
+ !readUByte(&img.tiles[tileIdx].tileComps[comp].transform)) {
1505
+ error(getPos(), "Error in JPX COC marker segment");
1506
+ return gFalse;
1507
+ }
1508
+ img.tiles[tileIdx].tileComps[comp].style =
1509
+ (img.tiles[tileIdx].tileComps[comp].style & ~1) | (style & 1);
1510
+ img.tiles[tileIdx].tileComps[comp].codeBlockW += 2;
1511
+ img.tiles[tileIdx].tileComps[comp].codeBlockH += 2;
1512
+ img.tiles[tileIdx].tileComps[comp].resLevels =
1513
+ (JPXResLevel *)greallocn(
1514
+ img.tiles[tileIdx].tileComps[comp].resLevels,
1515
+ (img.tiles[tileIdx].tileComps[comp].nDecompLevels + 1),
1516
+ sizeof(JPXResLevel));
1517
+ for (r = 0; r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; ++r) {
1518
+ img.tiles[tileIdx].tileComps[comp].resLevels[r].precincts = NULL;
1519
+ }
1520
+ for (r = 0; r <= img.tiles[tileIdx].tileComps[comp].nDecompLevels; ++r) {
1521
+ if (img.tiles[tileIdx].tileComps[comp].style & 0x01) {
1522
+ if (!readUByte(&precinctSize)) {
1523
+ error(getPos(), "Error in JPX COD marker segment");
1524
+ return gFalse;
1525
+ }
1526
+ img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth =
1527
+ precinctSize & 0x0f;
1528
+ img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight =
1529
+ (precinctSize >> 4) & 0x0f;
1530
+ } else {
1531
+ img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth = 15;
1532
+ img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight = 15;
1533
+ }
1534
+ }
1535
+ break;
1536
+ case 0x5c: // QCD - quantization default
1537
+ cover(36);
1538
+ if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantStyle)) {
1539
+ error(getPos(), "Error in JPX QCD marker segment");
1540
+ return gFalse;
1541
+ }
1542
+ if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x00) {
1543
+ img.tiles[tileIdx].tileComps[0].nQuantSteps =
1544
+ segLen - 3;
1545
+ img.tiles[tileIdx].tileComps[0].quantSteps =
1546
+ (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps,
1547
+ img.tiles[tileIdx].tileComps[0].nQuantSteps,
1548
+ sizeof(Guint));
1549
+ for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) {
1550
+ if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) {
1551
+ error(getPos(), "Error in JPX QCD marker segment");
1552
+ return gFalse;
1553
+ }
1554
+ }
1555
+ } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x01) {
1556
+ img.tiles[tileIdx].tileComps[0].nQuantSteps = 1;
1557
+ img.tiles[tileIdx].tileComps[0].quantSteps =
1558
+ (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps,
1559
+ img.tiles[tileIdx].tileComps[0].nQuantSteps,
1560
+ sizeof(Guint));
1561
+ if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[0])) {
1562
+ error(getPos(), "Error in JPX QCD marker segment");
1563
+ return gFalse;
1564
+ }
1565
+ } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x02) {
1566
+ img.tiles[tileIdx].tileComps[0].nQuantSteps = (segLen - 3) / 2;
1567
+ img.tiles[tileIdx].tileComps[0].quantSteps =
1568
+ (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps,
1569
+ img.tiles[tileIdx].tileComps[0].nQuantSteps,
1570
+ sizeof(Guint));
1571
+ for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) {
1572
+ if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) {
1573
+ error(getPos(), "Error in JPX QCD marker segment");
1574
+ return gFalse;
1575
+ }
1576
+ }
1577
+ } else {
1578
+ error(getPos(), "Error in JPX QCD marker segment");
1579
+ return gFalse;
1580
+ }
1581
+ for (comp = 1; comp < img.nComps; ++comp) {
1582
+ img.tiles[tileIdx].tileComps[comp].quantStyle =
1583
+ img.tiles[tileIdx].tileComps[0].quantStyle;
1584
+ img.tiles[tileIdx].tileComps[comp].nQuantSteps =
1585
+ img.tiles[tileIdx].tileComps[0].nQuantSteps;
1586
+ img.tiles[tileIdx].tileComps[comp].quantSteps =
1587
+ (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps,
1588
+ img.tiles[tileIdx].tileComps[0].nQuantSteps,
1589
+ sizeof(Guint));
1590
+ for (j = 0; j < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++j) {
1591
+ img.tiles[tileIdx].tileComps[comp].quantSteps[j] =
1592
+ img.tiles[tileIdx].tileComps[0].quantSteps[j];
1593
+ }
1594
+ }
1595
+ break;
1596
+ case 0x5d: // QCC - quantization component
1597
+ cover(37);
1598
+ if ((img.nComps > 256 && !readUWord(&comp)) ||
1599
+ (img.nComps <= 256 && !readUByte(&comp)) ||
1600
+ comp >= img.nComps ||
1601
+ !readUByte(&img.tiles[tileIdx].tileComps[comp].quantStyle)) {
1602
+ error(getPos(), "Error in JPX QCC marker segment");
1603
+ return gFalse;
1604
+ }
1605
+ if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f) == 0x00) {
1606
+ img.tiles[tileIdx].tileComps[comp].nQuantSteps =
1607
+ segLen - (img.nComps > 256 ? 5 : 4);
1608
+ img.tiles[tileIdx].tileComps[comp].quantSteps =
1609
+ (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps,
1610
+ img.tiles[tileIdx].tileComps[comp].nQuantSteps,
1611
+ sizeof(Guint));
1612
+ for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) {
1613
+ if (!readUByte(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) {
1614
+ error(getPos(), "Error in JPX QCC marker segment");
1615
+ return gFalse;
1616
+ }
1617
+ }
1618
+ } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f)
1619
+ == 0x01) {
1620
+ img.tiles[tileIdx].tileComps[comp].nQuantSteps = 1;
1621
+ img.tiles[tileIdx].tileComps[comp].quantSteps =
1622
+ (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps,
1623
+ img.tiles[tileIdx].tileComps[comp].nQuantSteps,
1624
+ sizeof(Guint));
1625
+ if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[0])) {
1626
+ error(getPos(), "Error in JPX QCC marker segment");
1627
+ return gFalse;
1628
+ }
1629
+ } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f)
1630
+ == 0x02) {
1631
+ img.tiles[tileIdx].tileComps[comp].nQuantSteps =
1632
+ (segLen - (img.nComps > 256 ? 5 : 4)) / 2;
1633
+ img.tiles[tileIdx].tileComps[comp].quantSteps =
1634
+ (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps,
1635
+ img.tiles[tileIdx].tileComps[comp].nQuantSteps,
1636
+ sizeof(Guint));
1637
+ for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) {
1638
+ if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) {
1639
+ error(getPos(), "Error in JPX QCD marker segment");
1640
+ return gFalse;
1641
+ }
1642
+ }
1643
+ } else {
1644
+ error(getPos(), "Error in JPX QCC marker segment");
1645
+ return gFalse;
1646
+ }
1647
+ break;
1648
+ case 0x5e: // RGN - region of interest
1649
+ cover(38);
1650
+ #if 1 //~ ROI is unimplemented
1651
+ fprintf(stderr, "RGN\n");
1652
+ for (i = 0; i < segLen - 2; ++i) {
1653
+ if (str->getChar() == EOF) {
1654
+ error(getPos(), "Error in JPX PPM marker segment");
1655
+ return gFalse;
1656
+ }
1657
+ }
1658
+ #else
1659
+ if ((img.nComps > 256 && !readUWord(&comp)) ||
1660
+ (img.nComps <= 256 && !readUByte(&comp)) ||
1661
+ comp >= img.nComps ||
1662
+ !readUByte(&compInfo[comp].roi.style) ||
1663
+ !readUByte(&compInfo[comp].roi.shift)) {
1664
+ error(getPos(), "Error in JPX RGN marker segment");
1665
+ return gFalse;
1666
+ }
1667
+ #endif
1668
+ break;
1669
+ case 0x5f: // POC - progression order change
1670
+ cover(39);
1671
+ #if 1 //~ progression order changes are unimplemented
1672
+ fprintf(stderr, "POC\n");
1673
+ for (i = 0; i < segLen - 2; ++i) {
1674
+ if (str->getChar() == EOF) {
1675
+ error(getPos(), "Error in JPX PPM marker segment");
1676
+ return gFalse;
1677
+ }
1678
+ }
1679
+ #else
1680
+ nTileProgs = (segLen - 2) / (img.nComps > 256 ? 9 : 7);
1681
+ tileProgs = (JPXProgOrder *)gmallocn(nTileProgs, sizeof(JPXProgOrder));
1682
+ for (i = 0; i < nTileProgs; ++i) {
1683
+ if (!readUByte(&tileProgs[i].startRes) ||
1684
+ !(img.nComps > 256 && readUWord(&tileProgs[i].startComp)) ||
1685
+ !(img.nComps <= 256 && readUByte(&tileProgs[i].startComp)) ||
1686
+ !readUWord(&tileProgs[i].endLayer) ||
1687
+ !readUByte(&tileProgs[i].endRes) ||
1688
+ !(img.nComps > 256 && readUWord(&tileProgs[i].endComp)) ||
1689
+ !(img.nComps <= 256 && readUByte(&tileProgs[i].endComp)) ||
1690
+ !readUByte(&tileProgs[i].progOrder)) {
1691
+ error(getPos(), "Error in JPX POC marker segment");
1692
+ return gFalse;
1693
+ }
1694
+ }
1695
+ #endif
1696
+ break;
1697
+ case 0x61: // PPT - packed packet headers, tile-part hdr
1698
+ cover(40);
1699
+ #if 1 //~ packed packet headers are unimplemented
1700
+ fprintf(stderr, "PPT\n");
1701
+ for (i = 0; i < segLen - 2; ++i) {
1702
+ if (str->getChar() == EOF) {
1703
+ error(getPos(), "Error in JPX PPT marker segment");
1704
+ return gFalse;
1705
+ }
1706
+ }
1707
+ #endif
1708
+ case 0x58: // PLT - packet length, tile-part header
1709
+ // skipped
1710
+ cover(41);
1711
+ for (i = 0; i < segLen - 2; ++i) {
1712
+ if (str->getChar() == EOF) {
1713
+ error(getPos(), "Error in JPX PLT marker segment");
1714
+ return gFalse;
1715
+ }
1716
+ }
1717
+ break;
1718
+ case 0x64: // COM - comment
1719
+ // skipped
1720
+ cover(42);
1721
+ for (i = 0; i < segLen - 2; ++i) {
1722
+ if (str->getChar() == EOF) {
1723
+ error(getPos(), "Error in JPX COM marker segment");
1724
+ return gFalse;
1725
+ }
1726
+ }
1727
+ break;
1728
+ case 0x93: // SOD - start of data
1729
+ cover(43);
1730
+ haveSOD = gTrue;
1731
+ break;
1732
+ default:
1733
+ cover(44);
1734
+ error(getPos(), "Unknown marker segment %02x in JPX tile-part stream",
1735
+ segType);
1736
+ for (i = 0; i < segLen - 2; ++i) {
1737
+ if (str->getChar() == EOF) {
1738
+ break;
1739
+ }
1740
+ }
1741
+ break;
1742
+ }
1743
+ } while (!haveSOD);
1744
+
1745
+ //----- initialize the tile, precincts, and code-blocks
1746
+ if (tilePartIdx == 0) {
1747
+ tile = &img.tiles[tileIdx];
1748
+ i = tileIdx / img.nXTiles;
1749
+ j = tileIdx % img.nXTiles;
1750
+ if ((tile->x0 = img.xTileOffset + j * img.xTileSize) < img.xOffset) {
1751
+ tile->x0 = img.xOffset;
1752
+ }
1753
+ if ((tile->y0 = img.yTileOffset + i * img.yTileSize) < img.yOffset) {
1754
+ tile->y0 = img.yOffset;
1755
+ }
1756
+ if ((tile->x1 = img.xTileOffset + (j + 1) * img.xTileSize) > img.xSize) {
1757
+ tile->x1 = img.xSize;
1758
+ }
1759
+ if ((tile->y1 = img.yTileOffset + (i + 1) * img.yTileSize) > img.ySize) {
1760
+ tile->y1 = img.ySize;
1761
+ }
1762
+ tile->comp = 0;
1763
+ tile->res = 0;
1764
+ tile->precinct = 0;
1765
+ tile->layer = 0;
1766
+ tile->maxNDecompLevels = 0;
1767
+ for (comp = 0; comp < img.nComps; ++comp) {
1768
+ tileComp = &tile->tileComps[comp];
1769
+ if (tileComp->nDecompLevels > tile->maxNDecompLevels) {
1770
+ tile->maxNDecompLevels = tileComp->nDecompLevels;
1771
+ }
1772
+ tileComp->x0 = jpxCeilDiv(tile->x0, tileComp->hSep);
1773
+ tileComp->y0 = jpxCeilDiv(tile->y0, tileComp->hSep);
1774
+ tileComp->x1 = jpxCeilDiv(tile->x1, tileComp->hSep);
1775
+ tileComp->y1 = jpxCeilDiv(tile->y1, tileComp->hSep);
1776
+ tileComp->cbW = 1 << tileComp->codeBlockW;
1777
+ tileComp->cbH = 1 << tileComp->codeBlockH;
1778
+ tileComp->data = (int *)gmallocn((tileComp->x1 - tileComp->x0) *
1779
+ (tileComp->y1 - tileComp->y0),
1780
+ sizeof(int));
1781
+ if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) {
1782
+ n = tileComp->x1 - tileComp->x0;
1783
+ } else {
1784
+ n = tileComp->y1 - tileComp->y0;
1785
+ }
1786
+ tileComp->buf = (int *)gmallocn(n + 8, sizeof(int));
1787
+ for (r = 0; r <= tileComp->nDecompLevels; ++r) {
1788
+ resLevel = &tileComp->resLevels[r];
1789
+ k = r == 0 ? tileComp->nDecompLevels
1790
+ : tileComp->nDecompLevels - r + 1;
1791
+ resLevel->x0 = jpxCeilDivPow2(tileComp->x0, k);
1792
+ resLevel->y0 = jpxCeilDivPow2(tileComp->y0, k);
1793
+ resLevel->x1 = jpxCeilDivPow2(tileComp->x1, k);
1794
+ resLevel->y1 = jpxCeilDivPow2(tileComp->y1, k);
1795
+ if (r == 0) {
1796
+ resLevel->bx0[0] = resLevel->x0;
1797
+ resLevel->by0[0] = resLevel->y0;
1798
+ resLevel->bx1[0] = resLevel->x1;
1799
+ resLevel->by1[0] = resLevel->y1;
1800
+ } else {
1801
+ resLevel->bx0[0] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k);
1802
+ resLevel->by0[0] = resLevel->y0;
1803
+ resLevel->bx1[0] = jpxCeilDivPow2(tileComp->x1 - (1 << (k-1)), k);
1804
+ resLevel->by1[0] = resLevel->y1;
1805
+ resLevel->bx0[1] = resLevel->x0;
1806
+ resLevel->by0[1] = jpxCeilDivPow2(tileComp->y0 - (1 << (k-1)), k);
1807
+ resLevel->bx1[1] = resLevel->x1;
1808
+ resLevel->by1[1] = jpxCeilDivPow2(tileComp->y1 - (1 << (k-1)), k);
1809
+ resLevel->bx0[2] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k);
1810
+ resLevel->by0[2] = jpxCeilDivPow2(tileComp->y0 - (1 << (k-1)), k);
1811
+ resLevel->bx1[2] = jpxCeilDivPow2(tileComp->x1 - (1 << (k-1)), k);
1812
+ resLevel->by1[2] = jpxCeilDivPow2(tileComp->y1 - (1 << (k-1)), k);
1813
+ }
1814
+ resLevel->precincts = (JPXPrecinct *)gmallocn(1, sizeof(JPXPrecinct));
1815
+ for (pre = 0; pre < 1; ++pre) {
1816
+ precinct = &resLevel->precincts[pre];
1817
+ precinct->x0 = resLevel->x0;
1818
+ precinct->y0 = resLevel->y0;
1819
+ precinct->x1 = resLevel->x1;
1820
+ precinct->y1 = resLevel->y1;
1821
+ nSBs = r == 0 ? 1 : 3;
1822
+ precinct->subbands =
1823
+ (JPXSubband *)gmallocn(nSBs, sizeof(JPXSubband));
1824
+ for (sb = 0; sb < nSBs; ++sb) {
1825
+ subband = &precinct->subbands[sb];
1826
+ subband->x0 = resLevel->bx0[sb];
1827
+ subband->y0 = resLevel->by0[sb];
1828
+ subband->x1 = resLevel->bx1[sb];
1829
+ subband->y1 = resLevel->by1[sb];
1830
+ subband->nXCBs = jpxCeilDivPow2(subband->x1,
1831
+ tileComp->codeBlockW)
1832
+ - jpxFloorDivPow2(subband->x0,
1833
+ tileComp->codeBlockW);
1834
+ subband->nYCBs = jpxCeilDivPow2(subband->y1,
1835
+ tileComp->codeBlockH)
1836
+ - jpxFloorDivPow2(subband->y0,
1837
+ tileComp->codeBlockH);
1838
+ n = subband->nXCBs > subband->nYCBs ? subband->nXCBs
1839
+ : subband->nYCBs;
1840
+ for (subband->maxTTLevel = 0, --n;
1841
+ n;
1842
+ ++subband->maxTTLevel, n >>= 1) ;
1843
+ n = 0;
1844
+ for (level = subband->maxTTLevel; level >= 0; --level) {
1845
+ nx = jpxCeilDivPow2(subband->nXCBs, level);
1846
+ ny = jpxCeilDivPow2(subband->nYCBs, level);
1847
+ n += nx * ny;
1848
+ }
1849
+ subband->inclusion =
1850
+ (JPXTagTreeNode *)gmallocn(n, sizeof(JPXTagTreeNode));
1851
+ subband->zeroBitPlane =
1852
+ (JPXTagTreeNode *)gmallocn(n, sizeof(JPXTagTreeNode));
1853
+ for (k = 0; k < n; ++k) {
1854
+ subband->inclusion[k].finished = gFalse;
1855
+ subband->inclusion[k].val = 0;
1856
+ subband->zeroBitPlane[k].finished = gFalse;
1857
+ subband->zeroBitPlane[k].val = 0;
1858
+ }
1859
+ subband->cbs = (JPXCodeBlock *)gmallocn(subband->nXCBs *
1860
+ subband->nYCBs,
1861
+ sizeof(JPXCodeBlock));
1862
+ sbx0 = jpxFloorDivPow2(subband->x0, tileComp->codeBlockW);
1863
+ sby0 = jpxFloorDivPow2(subband->y0, tileComp->codeBlockH);
1864
+ cb = subband->cbs;
1865
+ for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
1866
+ for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
1867
+ cb->x0 = (sbx0 + cbX) << tileComp->codeBlockW;
1868
+ cb->x1 = cb->x0 + tileComp->cbW;
1869
+ if (subband->x0 > cb->x0) {
1870
+ cb->x0 = subband->x0;
1871
+ }
1872
+ if (subband->x1 < cb->x1) {
1873
+ cb->x1 = subband->x1;
1874
+ }
1875
+ cb->y0 = (sby0 + cbY) << tileComp->codeBlockH;
1876
+ cb->y1 = cb->y0 + tileComp->cbH;
1877
+ if (subband->y0 > cb->y0) {
1878
+ cb->y0 = subband->y0;
1879
+ }
1880
+ if (subband->y1 < cb->y1) {
1881
+ cb->y1 = subband->y1;
1882
+ }
1883
+ cb->seen = gFalse;
1884
+ cb->lBlock = 3;
1885
+ cb->nextPass = jpxPassCleanup;
1886
+ cb->nZeroBitPlanes = 0;
1887
+ cb->coeffs =
1888
+ (JPXCoeff *)gmallocn((1 << (tileComp->codeBlockW
1889
+ + tileComp->codeBlockH)),
1890
+ sizeof(JPXCoeff));
1891
+ for (cbi = 0;
1892
+ cbi < (Guint)(1 << (tileComp->codeBlockW
1893
+ + tileComp->codeBlockH));
1894
+ ++cbi) {
1895
+ cb->coeffs[cbi].flags = 0;
1896
+ cb->coeffs[cbi].len = 0;
1897
+ cb->coeffs[cbi].mag = 0;
1898
+ }
1899
+ cb->arithDecoder = NULL;
1900
+ cb->stats = NULL;
1901
+ ++cb;
1902
+ }
1903
+ }
1904
+ }
1905
+ }
1906
+ }
1907
+ }
1908
+ }
1909
+
1910
+ return readTilePartData(tileIdx, tilePartLen, tilePartToEOC);
1911
+ }
1912
+
1913
+ GBool JPXStream::readTilePartData(Guint tileIdx,
1914
+ Guint tilePartLen, GBool tilePartToEOC) {
1915
+ JPXTile *tile;
1916
+ JPXTileComp *tileComp;
1917
+ JPXResLevel *resLevel;
1918
+ JPXPrecinct *precinct;
1919
+ JPXSubband *subband;
1920
+ JPXCodeBlock *cb;
1921
+ Guint ttVal;
1922
+ Guint bits, cbX, cbY, nx, ny, i, j, n, sb;
1923
+ int level;
1924
+
1925
+ tile = &img.tiles[tileIdx];
1926
+
1927
+ // read all packets from this tile-part
1928
+ while (1) {
1929
+ if (tilePartToEOC) {
1930
+ //~ peek for an EOC marker
1931
+ cover(93);
1932
+ } else if (tilePartLen == 0) {
1933
+ break;
1934
+ }
1935
+
1936
+ tileComp = &tile->tileComps[tile->comp];
1937
+ resLevel = &tileComp->resLevels[tile->res];
1938
+ precinct = &resLevel->precincts[tile->precinct];
1939
+
1940
+ //----- packet header
1941
+
1942
+ // setup
1943
+ startBitBuf(tilePartLen);
1944
+
1945
+ // zero-length flag
1946
+ if (!readBits(1, &bits)) {
1947
+ goto err;
1948
+ }
1949
+ if (!bits) {
1950
+ // packet is empty -- clear all code-block inclusion flags
1951
+ cover(45);
1952
+ for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
1953
+ subband = &precinct->subbands[sb];
1954
+ for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
1955
+ for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
1956
+ cb = &subband->cbs[cbY * subband->nXCBs + cbX];
1957
+ cb->included = gFalse;
1958
+ }
1959
+ }
1960
+ }
1961
+ } else {
1962
+
1963
+ for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
1964
+ subband = &precinct->subbands[sb];
1965
+ for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
1966
+ for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
1967
+ cb = &subband->cbs[cbY * subband->nXCBs + cbX];
1968
+
1969
+ // skip code-blocks with no coefficients
1970
+ if (cb->x0 >= cb->x1 || cb->y0 >= cb->y1) {
1971
+ cover(46);
1972
+ cb->included = gFalse;
1973
+ continue;
1974
+ }
1975
+
1976
+ // code-block inclusion
1977
+ if (cb->seen) {
1978
+ cover(47);
1979
+ if (!readBits(1, &cb->included)) {
1980
+ goto err;
1981
+ }
1982
+ } else {
1983
+ cover(48);
1984
+ ttVal = 0;
1985
+ i = 0;
1986
+ for (level = subband->maxTTLevel; level >= 0; --level) {
1987
+ nx = jpxCeilDivPow2(subband->nXCBs, level);
1988
+ ny = jpxCeilDivPow2(subband->nYCBs, level);
1989
+ j = i + (cbY >> level) * nx + (cbX >> level);
1990
+ if (!subband->inclusion[j].finished &&
1991
+ !subband->inclusion[j].val) {
1992
+ subband->inclusion[j].val = ttVal;
1993
+ } else {
1994
+ ttVal = subband->inclusion[j].val;
1995
+ }
1996
+ while (!subband->inclusion[j].finished &&
1997
+ ttVal <= tile->layer) {
1998
+ if (!readBits(1, &bits)) {
1999
+ goto err;
2000
+ }
2001
+ if (bits == 1) {
2002
+ subband->inclusion[j].finished = gTrue;
2003
+ } else {
2004
+ ++ttVal;
2005
+ }
2006
+ }
2007
+ subband->inclusion[j].val = ttVal;
2008
+ if (ttVal > tile->layer) {
2009
+ break;
2010
+ }
2011
+ i += nx * ny;
2012
+ }
2013
+ cb->included = level < 0;
2014
+ }
2015
+
2016
+ if (cb->included) {
2017
+ cover(49);
2018
+
2019
+ // zero bit-plane count
2020
+ if (!cb->seen) {
2021
+ cover(50);
2022
+ ttVal = 0;
2023
+ i = 0;
2024
+ for (level = subband->maxTTLevel; level >= 0; --level) {
2025
+ nx = jpxCeilDivPow2(subband->nXCBs, level);
2026
+ ny = jpxCeilDivPow2(subband->nYCBs, level);
2027
+ j = i + (cbY >> level) * nx + (cbX >> level);
2028
+ if (!subband->zeroBitPlane[j].finished &&
2029
+ !subband->zeroBitPlane[j].val) {
2030
+ subband->zeroBitPlane[j].val = ttVal;
2031
+ } else {
2032
+ ttVal = subband->zeroBitPlane[j].val;
2033
+ }
2034
+ while (!subband->zeroBitPlane[j].finished) {
2035
+ if (!readBits(1, &bits)) {
2036
+ goto err;
2037
+ }
2038
+ if (bits == 1) {
2039
+ subband->zeroBitPlane[j].finished = gTrue;
2040
+ } else {
2041
+ ++ttVal;
2042
+ }
2043
+ }
2044
+ subband->zeroBitPlane[j].val = ttVal;
2045
+ i += nx * ny;
2046
+ }
2047
+ cb->nZeroBitPlanes = ttVal;
2048
+ }
2049
+
2050
+ // number of coding passes
2051
+ if (!readBits(1, &bits)) {
2052
+ goto err;
2053
+ }
2054
+ if (bits == 0) {
2055
+ cover(51);
2056
+ cb->nCodingPasses = 1;
2057
+ } else {
2058
+ if (!readBits(1, &bits)) {
2059
+ goto err;
2060
+ }
2061
+ if (bits == 0) {
2062
+ cover(52);
2063
+ cb->nCodingPasses = 2;
2064
+ } else {
2065
+ cover(53);
2066
+ if (!readBits(2, &bits)) {
2067
+ goto err;
2068
+ }
2069
+ if (bits < 3) {
2070
+ cover(54);
2071
+ cb->nCodingPasses = 3 + bits;
2072
+ } else {
2073
+ cover(55);
2074
+ if (!readBits(5, &bits)) {
2075
+ goto err;
2076
+ }
2077
+ if (bits < 31) {
2078
+ cover(56);
2079
+ cb->nCodingPasses = 6 + bits;
2080
+ } else {
2081
+ cover(57);
2082
+ if (!readBits(7, &bits)) {
2083
+ goto err;
2084
+ }
2085
+ cb->nCodingPasses = 37 + bits;
2086
+ }
2087
+ }
2088
+ }
2089
+ }
2090
+
2091
+ // update Lblock
2092
+ while (1) {
2093
+ if (!readBits(1, &bits)) {
2094
+ goto err;
2095
+ }
2096
+ if (!bits) {
2097
+ break;
2098
+ }
2099
+ ++cb->lBlock;
2100
+ }
2101
+
2102
+ // length of compressed data
2103
+ //~ deal with multiple codeword segments
2104
+ for (n = cb->lBlock, i = cb->nCodingPasses >> 1;
2105
+ i;
2106
+ ++n, i >>= 1) ;
2107
+ if (!readBits(n, &cb->dataLen)) {
2108
+ goto err;
2109
+ }
2110
+ }
2111
+ }
2112
+ }
2113
+ }
2114
+ }
2115
+ tilePartLen = finishBitBuf();
2116
+
2117
+ //----- packet data
2118
+
2119
+ for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
2120
+ subband = &precinct->subbands[sb];
2121
+ for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
2122
+ for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
2123
+ cb = &subband->cbs[cbY * subband->nXCBs + cbX];
2124
+ if (cb->included) {
2125
+ if (!readCodeBlockData(tileComp, resLevel, precinct, subband,
2126
+ tile->res, sb, cb)) {
2127
+ return gFalse;
2128
+ }
2129
+ tilePartLen -= cb->dataLen;
2130
+ cb->seen = gTrue;
2131
+ }
2132
+ }
2133
+ }
2134
+ }
2135
+
2136
+ //----- next packet
2137
+
2138
+ switch (tile->progOrder) {
2139
+ case 0: // layer, resolution level, component, precinct
2140
+ cover(58);
2141
+ if (++tile->comp == img.nComps) {
2142
+ tile->comp = 0;
2143
+ if (++tile->res == tile->maxNDecompLevels + 1) {
2144
+ tile->res = 0;
2145
+ if (++tile->layer == tile->nLayers) {
2146
+ tile->layer = 0;
2147
+ }
2148
+ }
2149
+ }
2150
+ break;
2151
+ case 1: // resolution level, layer, component, precinct
2152
+ cover(59);
2153
+ if (++tile->comp == img.nComps) {
2154
+ tile->comp = 0;
2155
+ if (++tile->layer == tile->nLayers) {
2156
+ tile->layer = 0;
2157
+ if (++tile->res == tile->maxNDecompLevels + 1) {
2158
+ tile->res = 0;
2159
+ }
2160
+ }
2161
+ }
2162
+ break;
2163
+ case 2: // resolution level, precinct, component, layer
2164
+ //~ this isn't correct -- see B.12.1.3
2165
+ cover(60);
2166
+ if (++tile->layer == tile->nLayers) {
2167
+ tile->layer = 0;
2168
+ if (++tile->comp == img.nComps) {
2169
+ tile->comp = 0;
2170
+ if (++tile->res == tile->maxNDecompLevels + 1) {
2171
+ tile->res = 0;
2172
+ }
2173
+ }
2174
+ }
2175
+ break;
2176
+ case 3: // precinct, component, resolution level, layer
2177
+ //~ this isn't correct -- see B.12.1.4
2178
+ cover(61);
2179
+ if (++tile->layer == tile->nLayers) {
2180
+ tile->layer = 0;
2181
+ if (++tile->res == tile->maxNDecompLevels + 1) {
2182
+ tile->res = 0;
2183
+ if (++tile->comp == img.nComps) {
2184
+ tile->comp = 0;
2185
+ }
2186
+ }
2187
+ }
2188
+ break;
2189
+ case 4: // component, precinct, resolution level, layer
2190
+ //~ this isn't correct -- see B.12.1.5
2191
+ cover(62);
2192
+ if (++tile->layer == tile->nLayers) {
2193
+ tile->layer = 0;
2194
+ if (++tile->res == tile->maxNDecompLevels + 1) {
2195
+ tile->res = 0;
2196
+ if (++tile->comp == img.nComps) {
2197
+ tile->comp = 0;
2198
+ }
2199
+ }
2200
+ }
2201
+ break;
2202
+ }
2203
+ }
2204
+
2205
+ return gTrue;
2206
+
2207
+ err:
2208
+ error(getPos(), "Error in JPX stream");
2209
+ return gFalse;
2210
+ }
2211
+
2212
+ GBool JPXStream::readCodeBlockData(JPXTileComp *tileComp,
2213
+ JPXResLevel *resLevel,
2214
+ JPXPrecinct *precinct,
2215
+ JPXSubband *subband,
2216
+ Guint res, Guint sb,
2217
+ JPXCodeBlock *cb) {
2218
+ JPXCoeff *coeff0, *coeff1, *coeff;
2219
+ Guint horiz, vert, diag, all, cx, xorBit;
2220
+ int horizSign, vertSign;
2221
+ Guint i, x, y0, y1, y2;
2222
+
2223
+ if (cb->arithDecoder) {
2224
+ cover(63);
2225
+ cb->arithDecoder->restart(cb->dataLen);
2226
+ } else {
2227
+ cover(64);
2228
+ cb->arithDecoder = new JArithmeticDecoder();
2229
+ cb->arithDecoder->setStream(str, cb->dataLen);
2230
+ cb->arithDecoder->start();
2231
+ cb->stats = new JArithmeticDecoderStats(jpxNContexts);
2232
+ cb->stats->setEntry(jpxContextSigProp, 4, 0);
2233
+ cb->stats->setEntry(jpxContextRunLength, 3, 0);
2234
+ cb->stats->setEntry(jpxContextUniform, 46, 0);
2235
+ }
2236
+
2237
+ for (i = 0; i < cb->nCodingPasses; ++i) {
2238
+ switch (cb->nextPass) {
2239
+
2240
+ //----- significance propagation pass
2241
+ case jpxPassSigProp:
2242
+ cover(65);
2243
+ for (y0 = cb->y0, coeff0 = cb->coeffs;
2244
+ y0 < cb->y1;
2245
+ y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
2246
+ for (x = cb->x0, coeff1 = coeff0;
2247
+ x < cb->x1;
2248
+ ++x, ++coeff1) {
2249
+ for (y1 = 0, coeff = coeff1;
2250
+ y1 < 4 && y0+y1 < cb->y1;
2251
+ ++y1, coeff += tileComp->cbW) {
2252
+ if (!(coeff->flags & jpxCoeffSignificant)) {
2253
+ horiz = vert = diag = 0;
2254
+ horizSign = vertSign = 2;
2255
+ if (x > cb->x0) {
2256
+ if (coeff[-1].flags & jpxCoeffSignificant) {
2257
+ ++horiz;
2258
+ horizSign += (coeff[-1].flags & jpxCoeffSign) ? -1 : 1;
2259
+ }
2260
+ if (y0+y1 > cb->y0) {
2261
+ diag += (coeff[-(int)tileComp->cbW - 1].flags
2262
+ >> jpxCoeffSignificantB) & 1;
2263
+ }
2264
+ if (y0+y1 < cb->y1 - 1) {
2265
+ diag += (coeff[tileComp->cbW - 1].flags
2266
+ >> jpxCoeffSignificantB) & 1;
2267
+ }
2268
+ }
2269
+ if (x < cb->x1 - 1) {
2270
+ if (coeff[1].flags & jpxCoeffSignificant) {
2271
+ ++horiz;
2272
+ horizSign += (coeff[1].flags & jpxCoeffSign) ? -1 : 1;
2273
+ }
2274
+ if (y0+y1 > cb->y0) {
2275
+ diag += (coeff[-(int)tileComp->cbW + 1].flags
2276
+ >> jpxCoeffSignificantB) & 1;
2277
+ }
2278
+ if (y0+y1 < cb->y1 - 1) {
2279
+ diag += (coeff[tileComp->cbW + 1].flags
2280
+ >> jpxCoeffSignificantB) & 1;
2281
+ }
2282
+ }
2283
+ if (y0+y1 > cb->y0) {
2284
+ if (coeff[-(int)tileComp->cbW].flags & jpxCoeffSignificant) {
2285
+ ++vert;
2286
+ vertSign += (coeff[-(int)tileComp->cbW].flags & jpxCoeffSign)
2287
+ ? -1 : 1;
2288
+ }
2289
+ }
2290
+ if (y0+y1 < cb->y1 - 1) {
2291
+ if (coeff[tileComp->cbW].flags & jpxCoeffSignificant) {
2292
+ ++vert;
2293
+ vertSign += (coeff[tileComp->cbW].flags & jpxCoeffSign)
2294
+ ? -1 : 1;
2295
+ }
2296
+ }
2297
+ cx = sigPropContext[horiz][vert][diag][res == 0 ? 1 : sb];
2298
+ if (cx != 0) {
2299
+ if (cb->arithDecoder->decodeBit(cx, cb->stats)) {
2300
+ coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef;
2301
+ coeff->mag = (coeff->mag << 1) | 1;
2302
+ cx = signContext[horizSign][vertSign][0];
2303
+ xorBit = signContext[horizSign][vertSign][1];
2304
+ if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
2305
+ coeff->flags |= jpxCoeffSign;
2306
+ }
2307
+ }
2308
+ ++coeff->len;
2309
+ coeff->flags |= jpxCoeffTouched;
2310
+ }
2311
+ }
2312
+ }
2313
+ }
2314
+ }
2315
+ ++cb->nextPass;
2316
+ break;
2317
+
2318
+ //----- magnitude refinement pass
2319
+ case jpxPassMagRef:
2320
+ cover(66);
2321
+ for (y0 = cb->y0, coeff0 = cb->coeffs;
2322
+ y0 < cb->y1;
2323
+ y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
2324
+ for (x = cb->x0, coeff1 = coeff0;
2325
+ x < cb->x1;
2326
+ ++x, ++coeff1) {
2327
+ for (y1 = 0, coeff = coeff1;
2328
+ y1 < 4 && y0+y1 < cb->y1;
2329
+ ++y1, coeff += tileComp->cbW) {
2330
+ if ((coeff->flags & jpxCoeffSignificant) &&
2331
+ !(coeff->flags & jpxCoeffTouched)) {
2332
+ if (coeff->flags & jpxCoeffFirstMagRef) {
2333
+ all = 0;
2334
+ if (x > cb->x0) {
2335
+ all += (coeff[-1].flags >> jpxCoeffSignificantB) & 1;
2336
+ if (y0+y1 > cb->y0) {
2337
+ all += (coeff[-(int)tileComp->cbW - 1].flags
2338
+ >> jpxCoeffSignificantB) & 1;
2339
+ }
2340
+ if (y0+y1 < cb->y1 - 1) {
2341
+ all += (coeff[tileComp->cbW - 1].flags
2342
+ >> jpxCoeffSignificantB) & 1;
2343
+ }
2344
+ }
2345
+ if (x < cb->x1 - 1) {
2346
+ all += (coeff[1].flags >> jpxCoeffSignificantB) & 1;
2347
+ if (y0+y1 > cb->y0) {
2348
+ all += (coeff[-(int)tileComp->cbW + 1].flags
2349
+ >> jpxCoeffSignificantB) & 1;
2350
+ }
2351
+ if (y0+y1 < cb->y1 - 1) {
2352
+ all += (coeff[tileComp->cbW + 1].flags
2353
+ >> jpxCoeffSignificantB) & 1;
2354
+ }
2355
+ }
2356
+ if (y0+y1 > cb->y0) {
2357
+ all += (coeff[-(int)tileComp->cbW].flags
2358
+ >> jpxCoeffSignificantB) & 1;
2359
+ }
2360
+ if (y0+y1 < cb->y1 - 1) {
2361
+ all += (coeff[tileComp->cbW].flags
2362
+ >> jpxCoeffSignificantB) & 1;
2363
+ }
2364
+ cx = all ? 15 : 14;
2365
+ } else {
2366
+ cx = 16;
2367
+ }
2368
+ coeff->mag = (coeff->mag << 1) |
2369
+ cb->arithDecoder->decodeBit(cx, cb->stats);
2370
+ ++coeff->len;
2371
+ coeff->flags |= jpxCoeffTouched;
2372
+ coeff->flags &= ~jpxCoeffFirstMagRef;
2373
+ }
2374
+ }
2375
+ }
2376
+ }
2377
+ ++cb->nextPass;
2378
+ break;
2379
+
2380
+ //----- cleanup pass
2381
+ case jpxPassCleanup:
2382
+ cover(67);
2383
+ for (y0 = cb->y0, coeff0 = cb->coeffs;
2384
+ y0 < cb->y1;
2385
+ y0 += 4, coeff0 += 4 << tileComp->codeBlockW) {
2386
+ for (x = cb->x0, coeff1 = coeff0;
2387
+ x < cb->x1;
2388
+ ++x, ++coeff1) {
2389
+ y1 = 0;
2390
+ if (y0 + 3 < cb->y1 &&
2391
+ !(coeff1->flags & jpxCoeffTouched) &&
2392
+ !(coeff1[tileComp->cbW].flags & jpxCoeffTouched) &&
2393
+ !(coeff1[2 * tileComp->cbW].flags & jpxCoeffTouched) &&
2394
+ !(coeff1[3 * tileComp->cbW].flags & jpxCoeffTouched) &&
2395
+ (x == cb->x0 || y0 == cb->y0 ||
2396
+ !(coeff1[-(int)tileComp->cbW - 1].flags
2397
+ & jpxCoeffSignificant)) &&
2398
+ (y0 == cb->y0 ||
2399
+ !(coeff1[-(int)tileComp->cbW].flags
2400
+ & jpxCoeffSignificant)) &&
2401
+ (x == cb->x1 - 1 || y0 == cb->y0 ||
2402
+ !(coeff1[-(int)tileComp->cbW + 1].flags
2403
+ & jpxCoeffSignificant)) &&
2404
+ (x == cb->x0 ||
2405
+ (!(coeff1[-1].flags & jpxCoeffSignificant) &&
2406
+ !(coeff1[tileComp->cbW - 1].flags
2407
+ & jpxCoeffSignificant) &&
2408
+ !(coeff1[2 * tileComp->cbW - 1].flags
2409
+ & jpxCoeffSignificant) &&
2410
+ !(coeff1[3 * tileComp->cbW - 1].flags
2411
+ & jpxCoeffSignificant))) &&
2412
+ (x == cb->x1 - 1 ||
2413
+ (!(coeff1[1].flags & jpxCoeffSignificant) &&
2414
+ !(coeff1[tileComp->cbW + 1].flags
2415
+ & jpxCoeffSignificant) &&
2416
+ !(coeff1[2 * tileComp->cbW + 1].flags
2417
+ & jpxCoeffSignificant) &&
2418
+ !(coeff1[3 * tileComp->cbW + 1].flags
2419
+ & jpxCoeffSignificant))) &&
2420
+ (x == cb->x0 || y0+4 == cb->y1 ||
2421
+ !(coeff1[4 * tileComp->cbW - 1].flags & jpxCoeffSignificant)) &&
2422
+ (y0+4 == cb->y1 ||
2423
+ !(coeff1[4 * tileComp->cbW].flags & jpxCoeffSignificant)) &&
2424
+ (x == cb->x1 - 1 || y0+4 == cb->y1 ||
2425
+ !(coeff1[4 * tileComp->cbW + 1].flags
2426
+ & jpxCoeffSignificant))) {
2427
+ if (cb->arithDecoder->decodeBit(jpxContextRunLength, cb->stats)) {
2428
+ y1 = cb->arithDecoder->decodeBit(jpxContextUniform, cb->stats);
2429
+ y1 = (y1 << 1) |
2430
+ cb->arithDecoder->decodeBit(jpxContextUniform, cb->stats);
2431
+ for (y2 = 0, coeff = coeff1;
2432
+ y2 < y1;
2433
+ ++y2, coeff += tileComp->cbW) {
2434
+ ++coeff->len;
2435
+ }
2436
+ coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef;
2437
+ coeff->mag = (coeff->mag << 1) | 1;
2438
+ ++coeff->len;
2439
+ cx = signContext[2][2][0];
2440
+ xorBit = signContext[2][2][1];
2441
+ if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
2442
+ coeff->flags |= jpxCoeffSign;
2443
+ }
2444
+ ++y1;
2445
+ } else {
2446
+ for (y1 = 0, coeff = coeff1;
2447
+ y1 < 4;
2448
+ ++y1, coeff += tileComp->cbW) {
2449
+ ++coeff->len;
2450
+ }
2451
+ y1 = 4;
2452
+ }
2453
+ }
2454
+ for (coeff = &coeff1[y1 << tileComp->codeBlockW];
2455
+ y1 < 4 && y0 + y1 < cb->y1;
2456
+ ++y1, coeff += tileComp->cbW) {
2457
+ if (!(coeff->flags & jpxCoeffTouched)) {
2458
+ horiz = vert = diag = 0;
2459
+ horizSign = vertSign = 2;
2460
+ if (x > cb->x0) {
2461
+ if (coeff[-1].flags & jpxCoeffSignificant) {
2462
+ ++horiz;
2463
+ horizSign += (coeff[-1].flags & jpxCoeffSign) ? -1 : 1;
2464
+ }
2465
+ if (y0+y1 > cb->y0) {
2466
+ diag += (coeff[-(int)tileComp->cbW - 1].flags
2467
+ >> jpxCoeffSignificantB) & 1;
2468
+ }
2469
+ if (y0+y1 < cb->y1 - 1) {
2470
+ diag += (coeff[tileComp->cbW - 1].flags
2471
+ >> jpxCoeffSignificantB) & 1;
2472
+ }
2473
+ }
2474
+ if (x < cb->x1 - 1) {
2475
+ if (coeff[1].flags & jpxCoeffSignificant) {
2476
+ ++horiz;
2477
+ horizSign += (coeff[1].flags & jpxCoeffSign) ? -1 : 1;
2478
+ }
2479
+ if (y0+y1 > cb->y0) {
2480
+ diag += (coeff[-(int)tileComp->cbW + 1].flags
2481
+ >> jpxCoeffSignificantB) & 1;
2482
+ }
2483
+ if (y0+y1 < cb->y1 - 1) {
2484
+ diag += (coeff[tileComp->cbW + 1].flags
2485
+ >> jpxCoeffSignificantB) & 1;
2486
+ }
2487
+ }
2488
+ if (y0+y1 > cb->y0) {
2489
+ if (coeff[-(int)tileComp->cbW].flags & jpxCoeffSignificant) {
2490
+ ++vert;
2491
+ vertSign += (coeff[-(int)tileComp->cbW].flags & jpxCoeffSign)
2492
+ ? -1 : 1;
2493
+ }
2494
+ }
2495
+ if (y0+y1 < cb->y1 - 1) {
2496
+ if (coeff[tileComp->cbW].flags & jpxCoeffSignificant) {
2497
+ ++vert;
2498
+ vertSign += (coeff[tileComp->cbW].flags & jpxCoeffSign)
2499
+ ? -1 : 1;
2500
+ }
2501
+ }
2502
+ cx = sigPropContext[horiz][vert][diag][res == 0 ? 1 : sb];
2503
+ if (cb->arithDecoder->decodeBit(cx, cb->stats)) {
2504
+ coeff->flags |= jpxCoeffSignificant | jpxCoeffFirstMagRef;
2505
+ coeff->mag = (coeff->mag << 1) | 1;
2506
+ cx = signContext[horizSign][vertSign][0];
2507
+ xorBit = signContext[horizSign][vertSign][1];
2508
+ if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
2509
+ coeff->flags |= jpxCoeffSign;
2510
+ }
2511
+ }
2512
+ ++coeff->len;
2513
+ } else {
2514
+ coeff->flags &= ~jpxCoeffTouched;
2515
+ }
2516
+ }
2517
+ }
2518
+ }
2519
+ cb->nextPass = jpxPassSigProp;
2520
+ break;
2521
+ }
2522
+ }
2523
+
2524
+ cb->arithDecoder->cleanup();
2525
+ return gTrue;
2526
+ }
2527
+
2528
+ // Inverse quantization, and wavelet transform (IDWT). This also does
2529
+ // the initial shift to convert to fixed point format.
2530
+ void JPXStream::inverseTransform(JPXTileComp *tileComp) {
2531
+ JPXResLevel *resLevel;
2532
+ JPXPrecinct *precinct;
2533
+ JPXSubband *subband;
2534
+ JPXCodeBlock *cb;
2535
+ JPXCoeff *coeff0, *coeff;
2536
+ Guint qStyle, guard, eps, shift;
2537
+ int shift2;
2538
+ double mu;
2539
+ int val;
2540
+ int *dataPtr;
2541
+ Guint nx0, ny0, nx1, ny1;
2542
+ Guint r, cbX, cbY, x, y;
2543
+
2544
+ cover(68);
2545
+
2546
+ //----- (NL)LL subband (resolution level 0)
2547
+
2548
+ resLevel = &tileComp->resLevels[0];
2549
+ precinct = &resLevel->precincts[0];
2550
+ subband = &precinct->subbands[0];
2551
+
2552
+ // i-quant parameters
2553
+ qStyle = tileComp->quantStyle & 0x1f;
2554
+ guard = (tileComp->quantStyle >> 5) & 7;
2555
+ if (qStyle == 0) {
2556
+ cover(69);
2557
+ eps = (tileComp->quantSteps[0] >> 3) & 0x1f;
2558
+ shift = guard + eps - 1;
2559
+ mu = 0; // make gcc happy
2560
+ } else {
2561
+ cover(70);
2562
+ shift = guard - 1 + tileComp->prec;
2563
+ mu = (double)(0x800 + (tileComp->quantSteps[0] & 0x7ff)) / 2048.0;
2564
+ }
2565
+ if (tileComp->transform == 0) {
2566
+ cover(71);
2567
+ shift += fracBits;
2568
+ }
2569
+
2570
+ // copy (NL)LL into the upper-left corner of the data array, doing
2571
+ // the fixed point adjustment and dequantization along the way
2572
+ cb = subband->cbs;
2573
+ for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
2574
+ for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
2575
+ for (y = cb->y0, coeff0 = cb->coeffs;
2576
+ y < cb->y1;
2577
+ ++y, coeff0 += tileComp->cbW) {
2578
+ dataPtr = &tileComp->data[(y - subband->y0)
2579
+ * (tileComp->x1 - tileComp->x0)
2580
+ + (cb->x0 - subband->x0)];
2581
+ for (x = cb->x0, coeff = coeff0; x < cb->x1; ++x, ++coeff) {
2582
+ val = (int)coeff->mag;
2583
+ if (val != 0) {
2584
+ shift2 = shift - (cb->nZeroBitPlanes + coeff->len);
2585
+ if (shift2 > 0) {
2586
+ cover(94);
2587
+ val = (val << shift2) + (1 << (shift2 - 1));
2588
+ } else {
2589
+ cover(95);
2590
+ val >>= -shift2;
2591
+ }
2592
+ if (qStyle == 0) {
2593
+ cover(96);
2594
+ if (tileComp->transform == 0) {
2595
+ cover(97);
2596
+ val &= -1 << fracBits;
2597
+ }
2598
+ } else {
2599
+ cover(98);
2600
+ val = (int)((double)val * mu);
2601
+ }
2602
+ if (coeff->flags & jpxCoeffSign) {
2603
+ cover(99);
2604
+ val = -val;
2605
+ }
2606
+ }
2607
+ *dataPtr++ = val;
2608
+ }
2609
+ }
2610
+ ++cb;
2611
+ }
2612
+ }
2613
+
2614
+ //----- IDWT for each level
2615
+
2616
+ for (r = 1; r <= tileComp->nDecompLevels; ++r) {
2617
+ resLevel = &tileComp->resLevels[r];
2618
+
2619
+ // (n)LL is already in the upper-left corner of the
2620
+ // tile-component data array -- interleave with (n)HL/LH/HH
2621
+ // and inverse transform to get (n-1)LL, which will be stored
2622
+ // in the upper-left corner of the tile-component data array
2623
+ if (r == tileComp->nDecompLevels) {
2624
+ cover(72);
2625
+ nx0 = tileComp->x0;
2626
+ ny0 = tileComp->y0;
2627
+ nx1 = tileComp->x1;
2628
+ ny1 = tileComp->y1;
2629
+ } else {
2630
+ cover(73);
2631
+ nx0 = tileComp->resLevels[r+1].x0;
2632
+ ny0 = tileComp->resLevels[r+1].y0;
2633
+ nx1 = tileComp->resLevels[r+1].x1;
2634
+ ny1 = tileComp->resLevels[r+1].y1;
2635
+ }
2636
+ inverseTransformLevel(tileComp, r, resLevel, nx0, ny0, nx1, ny1);
2637
+ }
2638
+ }
2639
+
2640
+ // Do one level of the inverse transform:
2641
+ // - take (n)LL from the tile-component data array
2642
+ // - take (n)HL/LH/HH from <resLevel>
2643
+ // - leave the resulting (n-1)LL in the tile-component data array
2644
+ void JPXStream::inverseTransformLevel(JPXTileComp *tileComp,
2645
+ Guint r, JPXResLevel *resLevel,
2646
+ Guint nx0, Guint ny0,
2647
+ Guint nx1, Guint ny1) {
2648
+ JPXPrecinct *precinct;
2649
+ JPXSubband *subband;
2650
+ JPXCodeBlock *cb;
2651
+ JPXCoeff *coeff0, *coeff;
2652
+ Guint qStyle, guard, eps, shift, t;
2653
+ int shift2;
2654
+ double mu;
2655
+ int val;
2656
+ int *dataPtr;
2657
+ Guint xo, yo;
2658
+ Guint x, y, sb, cbX, cbY;
2659
+ int xx, yy;
2660
+
2661
+ //----- interleave
2662
+
2663
+ // spread out LL
2664
+ for (yy = resLevel->y1 - 1; yy >= (int)resLevel->y0; --yy) {
2665
+ for (xx = resLevel->x1 - 1; xx >= (int)resLevel->x0; --xx) {
2666
+ tileComp->data[(2 * yy - ny0) * (tileComp->x1 - tileComp->x0)
2667
+ + (2 * xx - nx0)] =
2668
+ tileComp->data[(yy - resLevel->y0) * (tileComp->x1 - tileComp->x0)
2669
+ + (xx - resLevel->x0)];
2670
+ }
2671
+ }
2672
+
2673
+ // i-quant parameters
2674
+ qStyle = tileComp->quantStyle & 0x1f;
2675
+ guard = (tileComp->quantStyle >> 5) & 7;
2676
+
2677
+ // interleave HL/LH/HH
2678
+ precinct = &resLevel->precincts[0];
2679
+ for (sb = 0; sb < 3; ++sb) {
2680
+
2681
+ // i-quant parameters
2682
+ if (qStyle == 0) {
2683
+ cover(100);
2684
+ eps = (tileComp->quantSteps[3*r - 2 + sb] >> 3) & 0x1f;
2685
+ shift = guard + eps - 1;
2686
+ mu = 0; // make gcc happy
2687
+ } else {
2688
+ cover(101);
2689
+ shift = guard + tileComp->prec;
2690
+ if (sb == 2) {
2691
+ cover(102);
2692
+ ++shift;
2693
+ }
2694
+ t = tileComp->quantSteps[qStyle == 1 ? 0 : (3*r - 2 + sb)];
2695
+ mu = (double)(0x800 + (t & 0x7ff)) / 2048.0;
2696
+ }
2697
+ if (tileComp->transform == 0) {
2698
+ cover(103);
2699
+ shift += fracBits;
2700
+ }
2701
+
2702
+ // copy the subband coefficients into the data array, doing the
2703
+ // fixed point adjustment and dequantization along the way
2704
+ xo = (sb & 1) ? 0 : 1;
2705
+ yo = (sb > 0) ? 1 : 0;
2706
+ subband = &precinct->subbands[sb];
2707
+ cb = subband->cbs;
2708
+ for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
2709
+ for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
2710
+ for (y = cb->y0, coeff0 = cb->coeffs;
2711
+ y < cb->y1;
2712
+ ++y, coeff0 += tileComp->cbW) {
2713
+ dataPtr = &tileComp->data[(2 * y + yo - ny0)
2714
+ * (tileComp->x1 - tileComp->x0)
2715
+ + (2 * cb->x0 + xo - nx0)];
2716
+ for (x = cb->x0, coeff = coeff0; x < cb->x1; ++x, ++coeff) {
2717
+ val = (int)coeff->mag;
2718
+ if (val != 0) {
2719
+ shift2 = shift - (cb->nZeroBitPlanes + coeff->len);
2720
+ if (shift2 > 0) {
2721
+ cover(74);
2722
+ val = (val << shift2) + (1 << (shift2 - 1));
2723
+ } else {
2724
+ cover(75);
2725
+ val >>= -shift2;
2726
+ }
2727
+ if (qStyle == 0) {
2728
+ cover(76);
2729
+ if (tileComp->transform == 0) {
2730
+ val &= -1 << fracBits;
2731
+ }
2732
+ } else {
2733
+ cover(77);
2734
+ val = (int)((double)val * mu);
2735
+ }
2736
+ if (coeff->flags & jpxCoeffSign) {
2737
+ cover(78);
2738
+ val = -val;
2739
+ }
2740
+ }
2741
+ *dataPtr = val;
2742
+ dataPtr += 2;
2743
+ }
2744
+ }
2745
+ ++cb;
2746
+ }
2747
+ }
2748
+ }
2749
+
2750
+ //----- horizontal (row) transforms
2751
+ dataPtr = tileComp->data;
2752
+ for (y = 0; y < ny1 - ny0; ++y) {
2753
+ inverseTransform1D(tileComp, dataPtr, 1, nx0, nx1);
2754
+ dataPtr += tileComp->x1 - tileComp->x0;
2755
+ }
2756
+
2757
+ //----- vertical (column) transforms
2758
+ dataPtr = tileComp->data;
2759
+ for (x = 0; x < nx1 - nx0; ++x) {
2760
+ inverseTransform1D(tileComp, dataPtr,
2761
+ tileComp->x1 - tileComp->x0, ny0, ny1);
2762
+ ++dataPtr;
2763
+ }
2764
+ }
2765
+
2766
+ void JPXStream::inverseTransform1D(JPXTileComp *tileComp,
2767
+ int *data, Guint stride,
2768
+ Guint i0, Guint i1) {
2769
+ int *buf;
2770
+ Guint offset, end, i;
2771
+
2772
+ //----- special case for length = 1
2773
+ if (i1 - i0 == 1) {
2774
+ cover(79);
2775
+ if (i0 & 1) {
2776
+ cover(104);
2777
+ *data >>= 1;
2778
+ }
2779
+
2780
+ } else {
2781
+ cover(80);
2782
+
2783
+ // choose an offset: this makes even buf[] indexes correspond to
2784
+ // odd values of i, and vice versa
2785
+ offset = 3 + (i0 & 1);
2786
+ end = offset + i1 - i0;
2787
+
2788
+ //----- gather
2789
+ buf = tileComp->buf;
2790
+ for (i = 0; i < i1 - i0; ++i) {
2791
+ buf[offset + i] = data[i * stride];
2792
+ }
2793
+
2794
+ //----- extend right
2795
+ buf[end] = buf[end - 2];
2796
+ if (i1 - i0 == 2) {
2797
+ cover(81);
2798
+ buf[end+1] = buf[offset + 1];
2799
+ buf[end+2] = buf[offset];
2800
+ buf[end+3] = buf[offset + 1];
2801
+ } else {
2802
+ cover(82);
2803
+ buf[end+1] = buf[end - 3];
2804
+ if (i1 - i0 == 3) {
2805
+ cover(105);
2806
+ buf[end+2] = buf[offset + 1];
2807
+ buf[end+3] = buf[offset + 2];
2808
+ } else {
2809
+ cover(106);
2810
+ buf[end+2] = buf[end - 4];
2811
+ if (i1 - i0 == 4) {
2812
+ cover(107);
2813
+ buf[end+3] = buf[offset + 1];
2814
+ } else {
2815
+ cover(108);
2816
+ buf[end+3] = buf[end - 5];
2817
+ }
2818
+ }
2819
+ }
2820
+
2821
+ //----- extend left
2822
+ buf[offset - 1] = buf[offset + 1];
2823
+ buf[offset - 2] = buf[offset + 2];
2824
+ buf[offset - 3] = buf[offset + 3];
2825
+ if (offset == 4) {
2826
+ cover(83);
2827
+ buf[0] = buf[offset + 4];
2828
+ }
2829
+
2830
+ //----- 9-7 irreversible filter
2831
+
2832
+ if (tileComp->transform == 0) {
2833
+ cover(84);
2834
+ // step 1 (even)
2835
+ for (i = 1; i <= end + 2; i += 2) {
2836
+ buf[i] = (int)(idwtKappa * buf[i]);
2837
+ }
2838
+ // step 2 (odd)
2839
+ for (i = 0; i <= end + 3; i += 2) {
2840
+ buf[i] = (int)(idwtIKappa * buf[i]);
2841
+ }
2842
+ // step 3 (even)
2843
+ for (i = 1; i <= end + 2; i += 2) {
2844
+ buf[i] = (int)(buf[i] - idwtDelta * (buf[i-1] + buf[i+1]));
2845
+ }
2846
+ // step 4 (odd)
2847
+ for (i = 2; i <= end + 1; i += 2) {
2848
+ buf[i] = (int)(buf[i] - idwtGamma * (buf[i-1] + buf[i+1]));
2849
+ }
2850
+ // step 5 (even)
2851
+ for (i = 3; i <= end; i += 2) {
2852
+ buf[i] = (int)(buf[i] - idwtBeta * (buf[i-1] + buf[i+1]));
2853
+ }
2854
+ // step 6 (odd)
2855
+ for (i = 4; i <= end - 1; i += 2) {
2856
+ buf[i] = (int)(buf[i] - idwtAlpha * (buf[i-1] + buf[i+1]));
2857
+ }
2858
+
2859
+ //----- 5-3 reversible filter
2860
+
2861
+ } else {
2862
+ cover(85);
2863
+ // step 1 (even)
2864
+ for (i = 3; i <= end; i += 2) {
2865
+ buf[i] -= (buf[i-1] + buf[i+1] + 2) >> 2;
2866
+ }
2867
+ // step 2 (odd)
2868
+ for (i = 4; i < end; i += 2) {
2869
+ buf[i] += (buf[i-1] + buf[i+1]) >> 1;
2870
+ }
2871
+ }
2872
+
2873
+ //----- scatter
2874
+ for (i = 0; i < i1 - i0; ++i) {
2875
+ data[i * stride] = buf[offset + i];
2876
+ }
2877
+ }
2878
+ }
2879
+
2880
+ // Inverse multi-component transform and DC level shift. This also
2881
+ // converts fixed point samples back to integers.
2882
+ GBool JPXStream::inverseMultiCompAndDC(JPXTile *tile) {
2883
+ JPXTileComp *tileComp;
2884
+ int coeff, d0, d1, d2, t, minVal, maxVal, zeroVal;
2885
+ int *dataPtr;
2886
+ Guint j, comp, x, y;
2887
+
2888
+ //----- inverse multi-component transform
2889
+
2890
+ if (tile->multiComp == 1) {
2891
+ cover(86);
2892
+ if (img.nComps < 3 ||
2893
+ tile->tileComps[0].hSep != tile->tileComps[1].hSep ||
2894
+ tile->tileComps[0].vSep != tile->tileComps[1].vSep ||
2895
+ tile->tileComps[1].hSep != tile->tileComps[2].hSep ||
2896
+ tile->tileComps[1].vSep != tile->tileComps[2].vSep) {
2897
+ return gFalse;
2898
+ }
2899
+
2900
+ // inverse irreversible multiple component transform
2901
+ if (tile->tileComps[0].transform == 0) {
2902
+ cover(87);
2903
+ j = 0;
2904
+ for (y = 0; y < tile->tileComps[0].y1 - tile->tileComps[0].y0; ++y) {
2905
+ for (x = 0; x < tile->tileComps[0].x1 - tile->tileComps[0].x0; ++x) {
2906
+ d0 = tile->tileComps[0].data[j];
2907
+ d1 = tile->tileComps[1].data[j];
2908
+ d2 = tile->tileComps[2].data[j];
2909
+ tile->tileComps[0].data[j] = (int)(d0 + 1.402 * d2 + 0.5);
2910
+ tile->tileComps[1].data[j] =
2911
+ (int)(d0 - 0.34413 * d1 - 0.71414 * d2 + 0.5);
2912
+ tile->tileComps[2].data[j] = (int)(d0 + 1.772 * d1 + 0.5);
2913
+ ++j;
2914
+ }
2915
+ }
2916
+
2917
+ // inverse reversible multiple component transform
2918
+ } else {
2919
+ cover(88);
2920
+ j = 0;
2921
+ for (y = 0; y < tile->tileComps[0].y1 - tile->tileComps[0].y0; ++y) {
2922
+ for (x = 0; x < tile->tileComps[0].x1 - tile->tileComps[0].x0; ++x) {
2923
+ d0 = tile->tileComps[0].data[j];
2924
+ d1 = tile->tileComps[1].data[j];
2925
+ d2 = tile->tileComps[2].data[j];
2926
+ tile->tileComps[1].data[j] = t = d0 - ((d2 + d1) >> 2);
2927
+ tile->tileComps[0].data[j] = d2 + t;
2928
+ tile->tileComps[2].data[j] = d1 + t;
2929
+ ++j;
2930
+ }
2931
+ }
2932
+ }
2933
+ }
2934
+
2935
+ //----- DC level shift
2936
+ for (comp = 0; comp < img.nComps; ++comp) {
2937
+ tileComp = &tile->tileComps[comp];
2938
+
2939
+ // signed: clip
2940
+ if (tileComp->sgned) {
2941
+ cover(89);
2942
+ minVal = -(1 << (tileComp->prec - 1));
2943
+ maxVal = (1 << (tileComp->prec - 1)) - 1;
2944
+ dataPtr = tileComp->data;
2945
+ for (y = 0; y < tileComp->y1 - tileComp->y0; ++y) {
2946
+ for (x = 0; x < tileComp->x1 - tileComp->x0; ++x) {
2947
+ coeff = *dataPtr;
2948
+ if (tileComp->transform == 0) {
2949
+ cover(109);
2950
+ coeff >>= fracBits;
2951
+ }
2952
+ if (coeff < minVal) {
2953
+ cover(110);
2954
+ coeff = minVal;
2955
+ } else if (coeff > maxVal) {
2956
+ cover(111);
2957
+ coeff = maxVal;
2958
+ }
2959
+ *dataPtr++ = coeff;
2960
+ }
2961
+ }
2962
+
2963
+ // unsigned: inverse DC level shift and clip
2964
+ } else {
2965
+ cover(90);
2966
+ maxVal = (1 << tileComp->prec) - 1;
2967
+ zeroVal = 1 << (tileComp->prec - 1);
2968
+ dataPtr = tileComp->data;
2969
+ for (y = 0; y < tileComp->y1 - tileComp->y0; ++y) {
2970
+ for (x = 0; x < tileComp->x1 - tileComp->x0; ++x) {
2971
+ coeff = *dataPtr;
2972
+ if (tileComp->transform == 0) {
2973
+ cover(112);
2974
+ coeff >>= fracBits;
2975
+ }
2976
+ coeff += zeroVal;
2977
+ if (coeff < 0) {
2978
+ cover(113);
2979
+ coeff = 0;
2980
+ } else if (coeff > maxVal) {
2981
+ cover(114);
2982
+ coeff = maxVal;
2983
+ }
2984
+ *dataPtr++ = coeff;
2985
+ }
2986
+ }
2987
+ }
2988
+ }
2989
+
2990
+ return gTrue;
2991
+ }
2992
+
2993
+ GBool JPXStream::readBoxHdr(Guint *boxType, Guint *boxLen, Guint *dataLen) {
2994
+ Guint len, lenH;
2995
+
2996
+ if (!readULong(&len) ||
2997
+ !readULong(boxType)) {
2998
+ return gFalse;
2999
+ }
3000
+ if (len == 1) {
3001
+ if (!readULong(&lenH) || !readULong(&len)) {
3002
+ return gFalse;
3003
+ }
3004
+ if (lenH) {
3005
+ error(getPos(), "JPX stream contains a box larger than 2^32 bytes");
3006
+ return gFalse;
3007
+ }
3008
+ *boxLen = len;
3009
+ *dataLen = len - 16;
3010
+ } else if (len == 0) {
3011
+ *boxLen = 0;
3012
+ *dataLen = 0;
3013
+ } else {
3014
+ *boxLen = len;
3015
+ *dataLen = len - 8;
3016
+ }
3017
+ return gTrue;
3018
+ }
3019
+
3020
+ int JPXStream::readMarkerHdr(int *segType, Guint *segLen) {
3021
+ int c;
3022
+
3023
+ do {
3024
+ do {
3025
+ if ((c = str->getChar()) == EOF) {
3026
+ return gFalse;
3027
+ }
3028
+ } while (c != 0xff);
3029
+ do {
3030
+ if ((c = str->getChar()) == EOF) {
3031
+ return gFalse;
3032
+ }
3033
+ } while (c == 0xff);
3034
+ } while (c == 0x00);
3035
+ *segType = c;
3036
+ if ((c >= 0x30 && c <= 0x3f) ||
3037
+ c == 0x4f || c == 0x92 || c == 0x93 || c == 0xd9) {
3038
+ *segLen = 0;
3039
+ return gTrue;
3040
+ }
3041
+ return readUWord(segLen);
3042
+ }
3043
+
3044
+ GBool JPXStream::readUByte(Guint *x) {
3045
+ int c0;
3046
+
3047
+ if ((c0 = str->getChar()) == EOF) {
3048
+ return gFalse;
3049
+ }
3050
+ *x = (Guint)c0;
3051
+ return gTrue;
3052
+ }
3053
+
3054
+ GBool JPXStream::readByte(int *x) {
3055
+ int c0;
3056
+
3057
+ if ((c0 = str->getChar()) == EOF) {
3058
+ return gFalse;
3059
+ }
3060
+ *x = c0;
3061
+ if (c0 & 0x80) {
3062
+ *x |= -1 - 0xff;
3063
+ }
3064
+ return gTrue;
3065
+ }
3066
+
3067
+ GBool JPXStream::readUWord(Guint *x) {
3068
+ int c0, c1;
3069
+
3070
+ if ((c0 = str->getChar()) == EOF ||
3071
+ (c1 = str->getChar()) == EOF) {
3072
+ return gFalse;
3073
+ }
3074
+ *x = (Guint)((c0 << 8) | c1);
3075
+ return gTrue;
3076
+ }
3077
+
3078
+ GBool JPXStream::readULong(Guint *x) {
3079
+ int c0, c1, c2, c3;
3080
+
3081
+ if ((c0 = str->getChar()) == EOF ||
3082
+ (c1 = str->getChar()) == EOF ||
3083
+ (c2 = str->getChar()) == EOF ||
3084
+ (c3 = str->getChar()) == EOF) {
3085
+ return gFalse;
3086
+ }
3087
+ *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3088
+ return gTrue;
3089
+ }
3090
+
3091
+ GBool JPXStream::readNBytes(int nBytes, GBool signd, int *x) {
3092
+ int y, c, i;
3093
+
3094
+ y = 0;
3095
+ for (i = 0; i < nBytes; ++i) {
3096
+ if ((c = str->getChar()) == EOF) {
3097
+ return gFalse;
3098
+ }
3099
+ y = (y << 8) + c;
3100
+ }
3101
+ if (signd) {
3102
+ if (y & (1 << (8 * nBytes - 1))) {
3103
+ y |= -1 << (8 * nBytes);
3104
+ }
3105
+ }
3106
+ *x = y;
3107
+ return gTrue;
3108
+ }
3109
+
3110
+ GBool JPXStream::readBits(int nBits, Guint *x) {
3111
+ int c;
3112
+
3113
+ while (bitBufLen < nBits) {
3114
+ if (byteCount == 0 || (c = str->getChar()) == EOF) {
3115
+ return gFalse;
3116
+ }
3117
+ --byteCount;
3118
+ if (bitBufSkip) {
3119
+ bitBuf = (bitBuf << 7) | (c & 0x7f);
3120
+ bitBufLen += 7;
3121
+ } else {
3122
+ bitBuf = (bitBuf << 8) | (c & 0xff);
3123
+ bitBufLen += 8;
3124
+ }
3125
+ bitBufSkip = c == 0xff;
3126
+ }
3127
+ *x = (bitBuf >> (bitBufLen - nBits)) & ((1 << nBits) - 1);
3128
+ bitBufLen -= nBits;
3129
+ return gTrue;
3130
+ }
3131
+
3132
+ void JPXStream::startBitBuf(Guint byteCountA) {
3133
+ bitBufLen = 0;
3134
+ bitBufSkip = gFalse;
3135
+ byteCount = byteCountA;
3136
+ }
3137
+
3138
+ Guint JPXStream::finishBitBuf() {
3139
+ if (bitBufSkip) {
3140
+ str->getChar();
3141
+ --byteCount;
3142
+ }
3143
+ return byteCount;
3144
+ }