void readSegment(Jbig2Segment s) { int ptr = _ra.FilePointer; if (s.DataLength == 0xffffffffL) { // TODO figure this bit out, 7.2.7 return; } byte[] data = new byte[(int)s.DataLength]; _ra.Read(data); s.Data = data; if (s.Type == PAGE_INFORMATION) { int last = _ra.FilePointer; _ra.Seek(ptr); int pageBitmapWidth = _ra.ReadInt(); int pageBitmapHeight = _ra.ReadInt(); _ra.Seek(last); Jbig2Page p = (Jbig2Page)_pages[s.Page]; if (p == null) { throw new InvalidOperationException("referring to widht/height of page we havent seen yet? " + s.Page); } p.PageBitmapWidth = pageBitmapWidth; p.PageBitmapHeight = pageBitmapHeight; } }
Jbig2Segment readHeader() { int ptr = _ra.FilePointer; // 7.2.1 int segmentNumber = _ra.ReadInt(); Jbig2Segment s = new Jbig2Segment(segmentNumber); // 7.2.3 int segmentHeaderFlags = _ra.Read(); bool deferredNonRetain = ((segmentHeaderFlags & 0x80) == 0x80); s.DeferredNonRetain = deferredNonRetain; bool pageAssociationSize = ((segmentHeaderFlags & 0x40) == 0x40); int segmentType = (segmentHeaderFlags & 0x3f); s.Type = segmentType; //7.2.4 int referredToByte0 = _ra.Read(); int countOfReferredToSegments = (referredToByte0 & 0xE0) >> 5; int[] referredToSegmentNumbers; bool[] segmentRetentionFlags = null; if (countOfReferredToSegments == 7) { // at least five bytes _ra.Seek(_ra.FilePointer - 1); countOfReferredToSegments = (_ra.ReadInt() & 0x1fffffff); segmentRetentionFlags = new bool[countOfReferredToSegments + 1]; int i = 0; int referredToCurrentByte = 0; do { int j = i % 8; if (j == 0) { referredToCurrentByte = _ra.Read(); } segmentRetentionFlags[i] = ((((0x1 << j) & referredToCurrentByte) >> j) == 0x1); i++; } while (i <= countOfReferredToSegments); } else if (countOfReferredToSegments <= 4) { // only one byte segmentRetentionFlags = new bool[countOfReferredToSegments + 1]; referredToByte0 &= 0x1f; for (int i = 0; i <= countOfReferredToSegments; i++) { segmentRetentionFlags[i] = ((((0x1 << i) & referredToByte0) >> i) == 0x1); } } else if (countOfReferredToSegments == 5 || countOfReferredToSegments == 6) { throw new InvalidOperationException("count of referred-to segments had bad value in header for segment " + segmentNumber + " starting at " + ptr); } s.SegmentRetentionFlags = segmentRetentionFlags; s.CountOfReferredToSegments = countOfReferredToSegments; // 7.2.5 referredToSegmentNumbers = new int[countOfReferredToSegments + 1]; for (int i = 1; i <= countOfReferredToSegments; i++) { if (segmentNumber <= 256) { referredToSegmentNumbers[i] = _ra.Read(); } else if (segmentNumber <= 65536) { referredToSegmentNumbers[i] = _ra.ReadUnsignedShort(); } else { referredToSegmentNumbers[i] = (int)_ra.ReadUnsignedInt(); // TODO wtf ack } } s.ReferredToSegmentNumbers = referredToSegmentNumbers; // 7.2.6 int segmentPageAssociation; int pageAssociationOffset = _ra.FilePointer - ptr; if (pageAssociationSize) { segmentPageAssociation = _ra.ReadInt(); } else { segmentPageAssociation = _ra.Read(); } if (segmentPageAssociation < 0) { throw new InvalidOperationException("page " + segmentPageAssociation + " invalid for segment " + segmentNumber + " starting at " + ptr); } s.Page = segmentPageAssociation; // so we can change the page association at embedding time. s.PageAssociationSize = pageAssociationSize; s.PageAssociationOffset = pageAssociationOffset; if (segmentPageAssociation > 0 && !_pages.ContainsKey(segmentPageAssociation)) { _pages[segmentPageAssociation] = new Jbig2Page(segmentPageAssociation, this); } if (segmentPageAssociation > 0) { ((Jbig2Page)_pages[segmentPageAssociation]).AddSegment(s); } else { _globals[s] = null; } // 7.2.7 long segmentDataLength = _ra.ReadUnsignedInt(); // TODO the 0xffffffff value that might be here, and how to understand those afflicted segments s.DataLength = segmentDataLength; int endPtr = _ra.FilePointer; _ra.Seek(ptr); byte[] headerData = new byte[endPtr - ptr]; _ra.Read(headerData); s.HeaderData = headerData; return(s); }