PageRenderTime 56ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/fstmerge/examples/iText/rev2818-4022/left-trunk-4022/core/com/lowagie/text/pdf/codec/JBIG2SegmentReader.java

https://github.com/RoDaniel/featurehouse
Java | 374 lines | 299 code | 75 blank | 0 comment | 69 complexity | 7633204a4956c6ffe1922c296f563aa9 MD5 | raw file
  1. package com.lowagie.text.pdf.codec;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import java.util.Iterator;
  5. import java.util.SortedMap;
  6. import java.util.SortedSet;
  7. import java.util.TreeMap;
  8. import java.util.TreeSet;
  9. import com.lowagie.text.pdf.RandomAccessFileOrArray;
  10. public class JBIG2SegmentReader {
  11. public static final int SYMBOL_DICTIONARY = 0;
  12. public static final int INTERMEDIATE_TEXT_REGION = 4;
  13. public static final int IMMEDIATE_TEXT_REGION = 6;
  14. public static final int IMMEDIATE_LOSSLESS_TEXT_REGION = 7;
  15. public static final int PATTERN_DICTIONARY = 16;
  16. public static final int INTERMEDIATE_HALFTONE_REGION = 20;
  17. public static final int IMMEDIATE_HALFTONE_REGION = 22;
  18. public static final int IMMEDIATE_LOSSLESS_HALFTONE_REGION = 23;
  19. public static final int INTERMEDIATE_GENERIC_REGION = 36;
  20. public static final int IMMEDIATE_GENERIC_REGION = 38;
  21. public static final int IMMEDIATE_LOSSLESS_GENERIC_REGION = 39;
  22. public static final int INTERMEDIATE_GENERIC_REFINEMENT_REGION = 40;
  23. public static final int IMMEDIATE_GENERIC_REFINEMENT_REGION = 42;
  24. public static final int IMMEDIATE_LOSSLESS_GENERIC_REFINEMENT_REGION = 43;
  25. public static final int PAGE_INFORMATION = 48;
  26. public static final int END_OF_PAGE = 49;
  27. public static final int END_OF_STRIPE = 50;
  28. public static final int END_OF_FILE = 51;
  29. public static final int PROFILES = 52;
  30. public static final int TABLES = 53;
  31. public static final int EXTENSION = 62;
  32. private final SortedMap segments = new TreeMap();
  33. private final SortedMap pages = new TreeMap();
  34. private final SortedSet globals = new TreeSet();
  35. private RandomAccessFileOrArray ra;
  36. private boolean sequential;
  37. private boolean number_of_pages_known;
  38. private int number_of_pages = -1;
  39. private boolean read = false;
  40. public static class JBIG2Segment implements Comparable {
  41. public final int segmentNumber;
  42. public long dataLength = -1;
  43. public int page = -1;
  44. public int[] referredToSegmentNumbers = null;
  45. public boolean[] segmentRetentionFlags = null;
  46. public int type = -1;
  47. public boolean deferredNonRetain = false;
  48. public int countOfReferredToSegments = -1;
  49. public byte[] data = null;
  50. public byte[] headerData = null;
  51. public boolean page_association_size = false;
  52. public int page_association_offset = -1;
  53. public JBIG2Segment(int segment_number) {
  54. this.segmentNumber = segment_number;
  55. }
  56. public int compareTo(Object o) {
  57. return this.compareTo((JBIG2Segment)o);
  58. }
  59. public int compareTo(JBIG2Segment s) {
  60. return this.segmentNumber - s.segmentNumber;
  61. }
  62. }
  63. public static class JBIG2Page {
  64. public final int page;
  65. private final JBIG2SegmentReader sr;
  66. private final SortedMap segs = new TreeMap();
  67. public int pageBitmapWidth = -1;
  68. public int pageBitmapHeight = -1;
  69. public JBIG2Page(int page, JBIG2SegmentReader sr) {
  70. this.page = page;
  71. this.sr = sr;
  72. }
  73. public byte[] getData(boolean for_embedding) throws IOException {
  74. ByteArrayOutputStream os = new ByteArrayOutputStream();
  75. for (Iterator i = segs.keySet().iterator(); i.hasNext(); ) {
  76. Integer sn = (Integer) i.next();
  77. JBIG2Segment s = (JBIG2Segment) segs.get(sn);
  78. if ( for_embedding &&
  79. ( s.type == END_OF_FILE || s.type == END_OF_PAGE ) ) {
  80. continue;
  81. }
  82. if ( for_embedding ) {
  83. byte[] headerData_emb = copyByteArray(s.headerData);
  84. if ( s.page_association_size ) {
  85. headerData_emb[s.page_association_offset] = 0x0;
  86. headerData_emb[s.page_association_offset+1] = 0x0;
  87. headerData_emb[s.page_association_offset+2] = 0x0;
  88. headerData_emb[s.page_association_offset+3] = 0x1;
  89. } else {
  90. headerData_emb[s.page_association_offset] = 0x1;
  91. }
  92. os.write(headerData_emb);
  93. } else {
  94. os.write(s.headerData);
  95. }
  96. os.write(s.data);
  97. }
  98. os.close();
  99. return os.toByteArray();
  100. }
  101. public void addSegment(JBIG2Segment s) {
  102. segs.put(new Integer(s.segmentNumber), s);
  103. }
  104. }
  105. public JBIG2SegmentReader(RandomAccessFileOrArray ra ) throws IOException {
  106. this.ra = ra;
  107. }
  108. public static byte[] copyByteArray(byte[] b) {
  109. byte[] bc = new byte[b.length];
  110. System.arraycopy(b, 0, bc, 0, b.length);
  111. return bc;
  112. }
  113. public void read() throws IOException {
  114. if ( this.read ) {
  115. throw new IllegalStateException("already attempted a read() on this Jbig2 File");
  116. }
  117. this.read = true;
  118. readFileHeader();
  119. if ( this.sequential ) {
  120. do {
  121. JBIG2Segment tmp = readHeader();
  122. readSegment(tmp);
  123. segments.put(new Integer(tmp.segmentNumber), tmp);
  124. } while ( this.ra.getFilePointer() < this.ra.length() );
  125. } else {
  126. JBIG2Segment tmp;
  127. do {
  128. tmp = readHeader();
  129. segments.put(new Integer(tmp.segmentNumber), tmp);
  130. } while ( tmp.type != END_OF_FILE );
  131. Iterator segs = segments.keySet().iterator();
  132. while ( segs.hasNext() ) {
  133. readSegment((JBIG2Segment)segments.get(segs.next()));
  134. }
  135. }
  136. }
  137. void readSegment(JBIG2Segment s) throws IOException {
  138. int ptr = ra.getFilePointer();
  139. if ( s.dataLength == 0xffffffffl ) {
  140. return;
  141. }
  142. byte[] data = new byte[(int)s.dataLength];
  143. ra.read(data);
  144. s.data = data;
  145. if ( s.type == PAGE_INFORMATION ) {
  146. int last = ra.getFilePointer();
  147. ra.seek(ptr);
  148. int page_bitmap_width = ra.readInt();
  149. int page_bitmap_height = ra.readInt();
  150. ra.seek(last);
  151. JBIG2Page p = (JBIG2Page)pages.get(new Integer(s.page));
  152. if ( p == null ) {
  153. throw new IllegalStateException("referring to widht/height of page we havent seen yet? " + s.page);
  154. }
  155. p.pageBitmapWidth = page_bitmap_width;
  156. p.pageBitmapHeight = page_bitmap_height;
  157. }
  158. }
  159. JBIG2Segment readHeader() throws IOException {
  160. int ptr = ra.getFilePointer();
  161. int segment_number = ra.readInt();
  162. JBIG2Segment s = new JBIG2Segment(segment_number);
  163. int segment_header_flags = ra.read();
  164. boolean deferred_non_retain = (( segment_header_flags & 0x80 ) == 0x80);
  165. s.deferredNonRetain = deferred_non_retain;
  166. boolean page_association_size = (( segment_header_flags & 0x40 ) == 0x40);
  167. int segment_type = ( segment_header_flags & 0x3f );
  168. s.type = segment_type;
  169. int referred_to_byte0 = ra.read();
  170. int count_of_referred_to_segments = (referred_to_byte0 & 0xE0) >> 5;
  171. int[] referred_to_segment_numbers = null;
  172. boolean[] segment_retention_flags = null;
  173. if ( count_of_referred_to_segments == 7 ) {
  174. ra.seek(ra.getFilePointer() - 1);
  175. count_of_referred_to_segments = ( ra.readInt() & 0x1fffffff );
  176. segment_retention_flags = new boolean[count_of_referred_to_segments+1];
  177. int i = 0;
  178. int referred_to_current_byte = 0;
  179. do {
  180. int j = i % 8;
  181. if ( j == 0) {
  182. referred_to_current_byte = ra.read();
  183. }
  184. segment_retention_flags[i] = (((( 0x1 << j ) & referred_to_current_byte) >> j) == 0x1);
  185. i++;
  186. } while ( i <= count_of_referred_to_segments );
  187. } else if ( count_of_referred_to_segments <= 4 ) {
  188. segment_retention_flags = new boolean[count_of_referred_to_segments+1];
  189. referred_to_byte0 &= 0x1f;
  190. for ( int i = 0; i <= count_of_referred_to_segments; i++ ) {
  191. segment_retention_flags[i] = (((( 0x1 << i ) & referred_to_byte0) >> i) == 0x1);
  192. }
  193. } else if ( count_of_referred_to_segments == 5 || count_of_referred_to_segments == 6 ) {
  194. throw new IllegalStateException("count of referred-to segments had bad value in header for segment " + segment_number + " starting at " + ptr);
  195. }
  196. s.segmentRetentionFlags = segment_retention_flags;
  197. s.countOfReferredToSegments = count_of_referred_to_segments;
  198. referred_to_segment_numbers = new int[count_of_referred_to_segments+1];
  199. for ( int i = 1; i <= count_of_referred_to_segments; i++ ) {
  200. if ( segment_number <= 256 ) {
  201. referred_to_segment_numbers[i] = ra.read();
  202. } else if ( segment_number <= 65536 ) {
  203. referred_to_segment_numbers[i] = ra.readUnsignedShort();
  204. } else {
  205. referred_to_segment_numbers[i] = (int)ra.readUnsignedInt();
  206. }
  207. }
  208. s.referredToSegmentNumbers = referred_to_segment_numbers;
  209. int segment_page_association;
  210. int page_association_offset = ra.getFilePointer() - ptr;
  211. if ( page_association_size ) {
  212. segment_page_association = ra.readInt();
  213. } else {
  214. segment_page_association = ra.read();
  215. }
  216. if ( segment_page_association < 0 ) {
  217. throw new IllegalStateException("page " + segment_page_association + " invalid for segment " + segment_number + " starting at " + ptr);
  218. }
  219. s.page = segment_page_association;
  220. s.page_association_size = page_association_size;
  221. s.page_association_offset = page_association_offset;
  222. if ( segment_page_association > 0 && ! pages.containsKey(new Integer(segment_page_association)) ) {
  223. pages.put(new Integer(segment_page_association), new JBIG2Page(segment_page_association, this));
  224. }
  225. if ( segment_page_association > 0 ) {
  226. ((JBIG2Page)pages.get(new Integer(segment_page_association))).addSegment(s);
  227. } else {
  228. globals.add(s);
  229. }
  230. long segment_data_length = ra.readUnsignedInt();
  231. s.dataLength = segment_data_length;
  232. int end_ptr = ra.getFilePointer();
  233. ra.seek(ptr);
  234. byte[] header_data = new byte[end_ptr - ptr];
  235. ra.read(header_data);
  236. s.headerData = header_data;
  237. return s;
  238. }
  239. void readFileHeader() throws IOException {
  240. ra.seek(0);
  241. byte[] idstring = new byte[8];
  242. ra.read(idstring);
  243. byte[] refidstring = {(byte)0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A};
  244. for ( int i = 0; i < idstring.length; i++ ) {
  245. if ( idstring[i] != refidstring[i] ) {
  246. throw new IllegalStateException("file header idstring not good at byte " + i);
  247. }
  248. }
  249. int fileheaderflags = ra.read();
  250. this.sequential = (( fileheaderflags & 0x1 ) == 0x1);
  251. this.number_of_pages_known = (( fileheaderflags & 0x2) == 0x0);
  252. if ( (fileheaderflags & 0xfc) != 0x0 ) {
  253. throw new IllegalStateException("file header flags bits 2-7 not 0");
  254. }
  255. if ( this.number_of_pages_known ) {
  256. this.number_of_pages = ra.readInt();
  257. }
  258. }
  259. public int numberOfPages() {
  260. return pages.size();
  261. }
  262. public int getPageHeight(int i) {
  263. return ((JBIG2Page)pages.get(new Integer(i))).pageBitmapHeight;
  264. }
  265. public int getPageWidth(int i) {
  266. return ((JBIG2Page)pages.get(new Integer(i))).pageBitmapWidth;
  267. }
  268. public JBIG2Page getPage(int page) {
  269. return (JBIG2Page)pages.get(new Integer(page));
  270. }
  271. public byte[] getGlobal(boolean for_embedding) {
  272. ByteArrayOutputStream os = new ByteArrayOutputStream();
  273. try {
  274. for (Iterator gitr = globals.iterator(); gitr.hasNext();) {
  275. JBIG2Segment s = (JBIG2Segment)gitr.next();
  276. if ( for_embedding &&
  277. ( s.type == END_OF_FILE || s.type == END_OF_PAGE ) ) {
  278. continue;
  279. }
  280. os.write(s.headerData);
  281. os.write(s.data);
  282. }
  283. os.close();
  284. } catch (IOException e) {
  285. e.printStackTrace();
  286. }
  287. if ( os.size() <= 0 ) {
  288. return null;
  289. }
  290. return os.toByteArray();
  291. }
  292. public String toString() {
  293. if ( this.read ) {
  294. return "Jbig2SegmentReader: number of pages: " + this.numberOfPages();
  295. } else {
  296. return "Jbig2SegmentReader in indeterminate state.";
  297. }
  298. }
  299. }