http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/JBIG2Page.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/JBIG2Page.java b/src/main/java/org/apache/pdfbox/jbig2/JBIG2Page.java index 566cdf7..8f48fc2 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/JBIG2Page.java +++ b/src/main/java/org/apache/pdfbox/jbig2/JBIG2Page.java @@ -38,339 +38,401 @@ import org.apache.pdfbox.jbig2.util.log.LoggerFactory; /** * This class represents a JBIG2 page. */ -class JBIG2Page { +class JBIG2Page +{ - private static final Logger log = LoggerFactory.getLogger(JBIG2Page.class); + private static final Logger log = LoggerFactory.getLogger(JBIG2Page.class); - /** - * This list contains all segments of this page, sorted by segment number in ascending order. - */ - private final Map<Integer, SegmentHeader> segments = new TreeMap<Integer, SegmentHeader>(); + /** + * This list contains all segments of this page, sorted by segment number in ascending order. + */ + private final Map<Integer, SegmentHeader> segments = new TreeMap<Integer, SegmentHeader>(); - /** NOTE: page number != segmentList index */ - private final int pageNumber; + /** NOTE: page number != segmentList index */ + private final int pageNumber; - /** The page bitmap that represents the page buffer */ - private Bitmap pageBitmap; + /** The page bitmap that represents the page buffer */ + private Bitmap pageBitmap; - private int finalHeight; - private int finalWidth; - private int resolutionX; - private int resolutionY; + private int finalHeight; + private int finalWidth; + private int resolutionX; + private int resolutionY; - private final JBIG2Document document; + private final JBIG2Document document; - protected JBIG2Page(JBIG2Document document, int pageNumber) { - this.document = document; - this.pageNumber = pageNumber; - } - - /** - * This method searches for a segment specified by its number. - * - * @param number - Segment number of the segment to search. - * - * @return The retrieved {@link SegmentHeader} or {@code null} if not available. - */ - public SegmentHeader getSegment(int number) { - SegmentHeader s = segments.get(number); - - if (null != s) { - return s; + protected JBIG2Page(JBIG2Document document, int pageNumber) + { + this.document = document; + this.pageNumber = pageNumber; } - if (null != document) { - return document.getGlobalSegment(number); + /** + * This method searches for a segment specified by its number. + * + * @param number - Segment number of the segment to search. + * + * @return The retrieved {@link SegmentHeader} or {@code null} if not available. + */ + public SegmentHeader getSegment(int number) + { + SegmentHeader s = segments.get(number); + + if (null != s) + { + return s; + } + + if (null != document) + { + return document.getGlobalSegment(number); + } + + log.info("Segment not found, returning null."); + return null; } - log.info("Segment not found, returning null."); - return null; - } - - /** - * Returns the associated page information segment. - * - * @return The associated {@link PageInformation} segment or {@code null} if not available. - */ - protected SegmentHeader getPageInformationSegment() { - for (SegmentHeader s : segments.values()) { - if (s.getSegmentType() == 48) { - return s; - } + /** + * Returns the associated page information segment. + * + * @return The associated {@link PageInformation} segment or {@code null} if not available. + */ + protected SegmentHeader getPageInformationSegment() + { + for (SegmentHeader s : segments.values()) + { + if (s.getSegmentType() == 48) + { + return s; + } + } + + log.info("Page information segment not found."); + return null; } - log.info("Page information segment not found."); - return null; - } - - /** - * This method returns the decoded bitmap if present. Otherwise the page bitmap will be composed - * before returning the result. - * - * @return pageBitmap - The result of decoding a page - * @throws JBIG2Exception - * @throws IOException - */ - protected Bitmap getBitmap() throws JBIG2Exception, IOException { - long timestamp; - - if (JBIG2ImageReader.PERFORMANCE_TEST) { - timestamp = System.currentTimeMillis(); + /** + * This method returns the decoded bitmap if present. Otherwise the page bitmap will be composed before returning + * the result. + * + * @return pageBitmap - The result of decoding a page + * @throws JBIG2Exception + * @throws IOException + */ + protected Bitmap getBitmap() throws JBIG2Exception, IOException + { + long timestamp; + + if (JBIG2ImageReader.PERFORMANCE_TEST) + { + timestamp = System.currentTimeMillis(); + } + + if (null == pageBitmap) + { + composePageBitmap(); + } + + if (JBIG2ImageReader.PERFORMANCE_TEST) + { + log.info("PAGE DECODING: " + (System.currentTimeMillis() - timestamp) + " ms"); + } + + return pageBitmap; } - if (null == pageBitmap) { - composePageBitmap(); + /** + * This method composes the segments' bitmaps to a page and stores the page as a {@link Bitmap} + * + * @throws IOException + * @throws JBIG2Exception + */ + private void composePageBitmap() throws IOException, JBIG2Exception + { + if (pageNumber > 0) + { + // Page 79, 1) Decoding the page information segment + PageInformation pageInformation = (PageInformation) getPageInformationSegment() + .getSegmentData(); + createPage(pageInformation); + clearSegmentData(); + } } - if (JBIG2ImageReader.PERFORMANCE_TEST) { - log.info("PAGE DECODING: " + (System.currentTimeMillis() - timestamp) + " ms"); + private void createPage(PageInformation pageInformation) + throws IOException, IntegerMaxValueException, InvalidHeaderValueException + { + if (!pageInformation.isStriped() || pageInformation.getHeight() != -1) + { + // Page 79, 4) + createNormalPage(pageInformation); + } + else + { + createStripedPage(pageInformation); + } } - return pageBitmap; - } - - /** - * This method composes the segments' bitmaps to a page and stores the page as a {@link Bitmap} - * - * @throws IOException - * @throws JBIG2Exception - */ - private void composePageBitmap() throws IOException, JBIG2Exception { - if (pageNumber > 0) { - // Page 79, 1) Decoding the page information segment - PageInformation pageInformation = (PageInformation) getPageInformationSegment().getSegmentData(); - createPage(pageInformation); - clearSegmentData(); - } - } - - private void createPage(PageInformation pageInformation) throws IOException, IntegerMaxValueException, - InvalidHeaderValueException { - if (!pageInformation.isStriped() || pageInformation.getHeight() != -1) { - // Page 79, 4) - createNormalPage(pageInformation); - } else { - createStripedPage(pageInformation); + private void createNormalPage(PageInformation pageInformation) + throws IOException, IntegerMaxValueException, InvalidHeaderValueException + { + + pageBitmap = new Bitmap(pageInformation.getWidth(), pageInformation.getHeight()); + + // Page 79, 3) + // If default pixel value is not 0, byte will be filled with 0xff + if (pageInformation.getDefaultPixelValue() != 0) + { + Arrays.fill(pageBitmap.getByteArray(), (byte) 0xff); + } + + for (SegmentHeader s : segments.values()) + { + // Page 79, 5) + switch (s.getSegmentType()) + { + case 6: // Immediate text region + case 7: // Immediate lossless text region + case 22: // Immediate halftone region + case 23: // Immediate lossless halftone region + case 38: // Immediate generic region + case 39: // Immediate lossless generic region + case 42: // Immediate generic refinement region + case 43: // Immediate lossless generic refinement region + final Region r = (Region) s.getSegmentData(); + + final Bitmap regionBitmap = r.getRegionBitmap(); + + if (fitsPage(pageInformation, regionBitmap)) + { + pageBitmap = regionBitmap; + } + else + { + final RegionSegmentInformation regionInfo = r.getRegionInfo(); + final CombinationOperator op = getCombinationOperator(pageInformation, + regionInfo.getCombinationOperator()); + Bitmaps.blit(regionBitmap, pageBitmap, regionInfo.getXLocation(), + regionInfo.getYLocation(), op); + } + + break; + } + } } - } - private void createNormalPage(PageInformation pageInformation) throws IOException, IntegerMaxValueException, - InvalidHeaderValueException { - - pageBitmap = new Bitmap(pageInformation.getWidth(), pageInformation.getHeight()); + /** + * Check if we have only one region that forms the complete page. If the dimension equals the page's dimension set + * the region's bitmap as the page's bitmap. Otherwise we have to blit the smaller region's bitmap into the page's + * bitmap (see Issue 6). + * + * @param pageInformation + * @param regionBitmap + * @return + */ + private boolean fitsPage(PageInformation pageInformation, final Bitmap regionBitmap) + { + return countRegions() == 1 && pageInformation.getDefaultPixelValue() == 0 + && pageInformation.getWidth() == regionBitmap.getWidth() + && pageInformation.getHeight() == regionBitmap.getHeight(); + } - // Page 79, 3) - // If default pixel value is not 0, byte will be filled with 0xff - if (pageInformation.getDefaultPixelValue() != 0) { - Arrays.fill(pageBitmap.getByteArray(), (byte) 0xff); + private void createStripedPage(PageInformation pageInformation) + throws IOException, IntegerMaxValueException, InvalidHeaderValueException + { + final ArrayList<SegmentData> pageStripes = collectPageStripes(); + + pageBitmap = new Bitmap(pageInformation.getWidth(), finalHeight); + + int startLine = 0; + for (SegmentData sd : pageStripes) + { + if (sd instanceof EndOfStripe) + { + startLine = ((EndOfStripe) sd).getLineNumber() + 1; + } + else + { + final Region r = (Region) sd; + final RegionSegmentInformation regionInfo = r.getRegionInfo(); + final CombinationOperator op = getCombinationOperator(pageInformation, + regionInfo.getCombinationOperator()); + Bitmaps.blit(r.getRegionBitmap(), pageBitmap, regionInfo.getXLocation(), startLine, + op); + } + } } - for (SegmentHeader s : segments.values()) { - // Page 79, 5) - switch (s.getSegmentType()){ - case 6 : // Immediate text region - case 7 : // Immediate lossless text region - case 22 : // Immediate halftone region - case 23 : // Immediate lossless halftone region - case 38 : // Immediate generic region - case 39 : // Immediate lossless generic region - case 42 : // Immediate generic refinement region - case 43 : // Immediate lossless generic refinement region - final Region r = (Region) s.getSegmentData(); - - final Bitmap regionBitmap = r.getRegionBitmap(); - - if (fitsPage(pageInformation, regionBitmap)) { - pageBitmap = regionBitmap; - } else { - final RegionSegmentInformation regionInfo = r.getRegionInfo(); - final CombinationOperator op = getCombinationOperator(pageInformation, - regionInfo.getCombinationOperator()); - Bitmaps.blit(regionBitmap, pageBitmap, regionInfo.getXLocation(), regionInfo.getYLocation(), op); - } - - break; - } + private ArrayList<SegmentData> collectPageStripes() + { + final ArrayList<SegmentData> pageStripes = new ArrayList<SegmentData>(); + for (SegmentHeader s : segments.values()) + { + // Page 79, 5) + switch (s.getSegmentType()) + { + case 6: // Immediate text region + case 7: // Immediate lossless text region + case 22: // Immediate halftone region + case 23: // Immediate lossless halftone region + case 38: // Immediate generic region + case 39: // Immediate lossless generic region + case 42: // Immediate generic refinement region + case 43: // Immediate lossless generic refinement region + Region r = (Region) s.getSegmentData(); + pageStripes.add(r); + break; + + case 50: // End of stripe + EndOfStripe eos = (EndOfStripe) s.getSegmentData(); + pageStripes.add(eos); + finalHeight = eos.getLineNumber() + 1; + break; + } + } + + return pageStripes; } - } - - /** - * Check if we have only one region that forms the complete page. If the dimension equals the - * page's dimension set the region's bitmap as the page's bitmap. Otherwise we have to blit the - * smaller region's bitmap into the page's bitmap (see Issue 6). - * - * @param pageInformation - * @param regionBitmap - * @return - */ - private boolean fitsPage(PageInformation pageInformation, final Bitmap regionBitmap) { - return countRegions() == 1 && pageInformation.getDefaultPixelValue() == 0 - && pageInformation.getWidth() == regionBitmap.getWidth() - && pageInformation.getHeight() == regionBitmap.getHeight(); - } - - private void createStripedPage(PageInformation pageInformation) throws IOException, IntegerMaxValueException, - InvalidHeaderValueException { - final ArrayList<SegmentData> pageStripes = collectPageStripes(); - - pageBitmap = new Bitmap(pageInformation.getWidth(), finalHeight); - - int startLine = 0; - for (SegmentData sd : pageStripes) { - if (sd instanceof EndOfStripe) { - startLine = ((EndOfStripe) sd).getLineNumber() + 1; - } else { - final Region r = (Region) sd; - final RegionSegmentInformation regionInfo = r.getRegionInfo(); - final CombinationOperator op = getCombinationOperator(pageInformation, regionInfo.getCombinationOperator()); - Bitmaps.blit(r.getRegionBitmap(), pageBitmap, regionInfo.getXLocation(), startLine, op); - } + + /** + * This method counts the regions segments. If there is only one region, the bitmap of this segment is equal to the + * page bitmap and blitting is not necessary. + * + * @return Amount of regions. + */ + private int countRegions() + { + int regionCount = 0; + + for (SegmentHeader s : segments.values()) + { + switch (s.getSegmentType()) + { + case 6: // Immediate text region + case 7: // Immediate lossless text region + case 22: // Immediate halftone region + case 23: // Immediate lossless halftone region + case 38: // Immediate generic region + case 39: // Immediate lossless generic region + case 42: // Immediate generic refinement region + case 43: // Immediate lossless generic refinement region + regionCount++; + } + } + + return regionCount; } - } - - private ArrayList<SegmentData> collectPageStripes() { - final ArrayList<SegmentData> pageStripes = new ArrayList<SegmentData>(); - for (SegmentHeader s : segments.values()) { - // Page 79, 5) - switch (s.getSegmentType()){ - case 6 : // Immediate text region - case 7 : // Immediate lossless text region - case 22 : // Immediate halftone region - case 23 : // Immediate lossless halftone region - case 38 : // Immediate generic region - case 39 : // Immediate lossless generic region - case 42 : // Immediate generic refinement region - case 43 : // Immediate lossless generic refinement region - Region r = (Region) s.getSegmentData(); - pageStripes.add(r); - break; - - case 50 : // End of stripe - EndOfStripe eos = (EndOfStripe) s.getSegmentData(); - pageStripes.add(eos); - finalHeight = eos.getLineNumber() + 1; - break; - } + + /** + * This method checks and sets, which combination operator shall be used. + * + * @param pi - <code>PageInformation</code> object + * @param newOperator - The combination operator, specified by actual segment + * @return the new combination operator + */ + private CombinationOperator getCombinationOperator(PageInformation pi, + CombinationOperator newOperator) + { + if (pi.isCombinationOperatorOverrideAllowed()) + { + return newOperator; + } + else + { + return pi.getCombinationOperator(); + } } - return pageStripes; - } - - /** - * This method counts the regions segments. If there is only one region, the bitmap of this - * segment is equal to the page bitmap and blitting is not necessary. - * - * @return Amount of regions. - */ - private int countRegions() { - int regionCount = 0; - - for (SegmentHeader s : segments.values()) { - switch (s.getSegmentType()){ - case 6 : // Immediate text region - case 7 : // Immediate lossless text region - case 22 : // Immediate halftone region - case 23 : // Immediate lossless halftone region - case 38 : // Immediate generic region - case 39 : // Immediate lossless generic region - case 42 : // Immediate generic refinement region - case 43 : // Immediate lossless generic refinement region - regionCount++; - } + /** + * Adds a {@link SegmentHeader} into the page's segments map. + * + * @param segment - The segment to be added. + */ + protected void add(SegmentHeader segment) + { + + segments.put(segment.getSegmentNr(), segment); } - return regionCount; - } - - /** - * This method checks and sets, which combination operator shall be used. - * - * @param pi - <code>PageInformation</code> object - * @param newOperator - The combination operator, specified by actual segment - * @return the new combination operator - */ - private CombinationOperator getCombinationOperator(PageInformation pi, CombinationOperator newOperator) { - if (pi.isCombinationOperatorOverrideAllowed()) { - return newOperator; - } else { - return pi.getCombinationOperator(); + /** + * Resets the memory-critical segments to force on-demand-decoding and to avoid holding the segments' bitmap too + * long. + */ + private void clearSegmentData() + { + Set<Integer> keySet = segments.keySet(); + + for (Integer key : keySet) + { + segments.get(key).cleanSegmentData(); + } } - } - - /** - * Adds a {@link SegmentHeader} into the page's segments map. - * - * @param segment - The segment to be added. - */ - protected void add(SegmentHeader segment) { - - segments.put(segment.getSegmentNr(), segment); - } - - /** - * Resets the memory-critical segments to force on-demand-decoding and to avoid holding the - * segments' bitmap too long. - */ - private void clearSegmentData() { - Set<Integer> keySet = segments.keySet(); - - for (Integer key : keySet) { - segments.get(key).cleanSegmentData(); + + /** + * Reset memory-critical parts of page. + */ + protected void clearPageData() + { + pageBitmap = null; } - } - - /** - * Reset memory-critical parts of page. - */ - protected void clearPageData() { - pageBitmap = null; - } - - /** - * Returns the final height of the page. - * - * @return The final height of the page. - * @throws IOException - * @throws JBIG2Exception - */ - protected int getHeight() throws IOException, JBIG2Exception { - if (finalHeight == 0) { - PageInformation pi = (PageInformation) getPageInformationSegment().getSegmentData(); - if (pi.getHeight() == 0xffffffff) { - getBitmap(); - } else { - finalHeight = pi.getHeight(); - } + + /** + * Returns the final height of the page. + * + * @return The final height of the page. + * @throws IOException + * @throws JBIG2Exception + */ + protected int getHeight() throws IOException, JBIG2Exception + { + if (finalHeight == 0) + { + PageInformation pi = (PageInformation) getPageInformationSegment().getSegmentData(); + if (pi.getHeight() == 0xffffffff) + { + getBitmap(); + } + else + { + finalHeight = pi.getHeight(); + } + } + return finalHeight; } - return finalHeight; - } - protected int getWidth() { - if (finalWidth == 0) { - PageInformation pi = (PageInformation) getPageInformationSegment().getSegmentData(); - finalWidth = pi.getWidth(); + protected int getWidth() + { + if (finalWidth == 0) + { + PageInformation pi = (PageInformation) getPageInformationSegment().getSegmentData(); + finalWidth = pi.getWidth(); + } + return finalWidth; } - return finalWidth; - } - protected int getResolutionX() { - if (resolutionX == 0) { - PageInformation pi = (PageInformation) getPageInformationSegment().getSegmentData(); - resolutionX = pi.getResolutionX(); + protected int getResolutionX() + { + if (resolutionX == 0) + { + PageInformation pi = (PageInformation) getPageInformationSegment().getSegmentData(); + resolutionX = pi.getResolutionX(); + } + return resolutionX; } - return resolutionX; - } - protected int getResolutionY() { - if (resolutionY == 0) { - PageInformation pi = (PageInformation) getPageInformationSegment().getSegmentData(); - resolutionY = pi.getResolutionY(); + protected int getResolutionY() + { + if (resolutionY == 0) + { + PageInformation pi = (PageInformation) getPageInformationSegment().getSegmentData(); + resolutionY = pi.getResolutionY(); + } + return resolutionY; } - return resolutionY; - } - @Override - public String toString() { - return getClass().getSimpleName() + " (Page number: " + pageNumber + ")"; - } + @Override + public String toString() + { + return getClass().getSimpleName() + " (Page number: " + pageNumber + ")"; + } }
http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/JBIG2ReadParam.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/JBIG2ReadParam.java b/src/main/java/org/apache/pdfbox/jbig2/JBIG2ReadParam.java index 7554df2..b8fa158 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/JBIG2ReadParam.java +++ b/src/main/java/org/apache/pdfbox/jbig2/JBIG2ReadParam.java @@ -23,26 +23,33 @@ import java.awt.Rectangle; import javax.imageio.ImageReadParam; /** - * This class extends {@code ImageReadParam} and contains region of interest and scale / subsampling - * functionality + * This class extends {@code ImageReadParam} and contains region of interest and scale / subsampling functionality */ -public class JBIG2ReadParam extends ImageReadParam { +public class JBIG2ReadParam extends ImageReadParam +{ - public JBIG2ReadParam() { - this(1, 1, 0, 0, null, null); - } - - public JBIG2ReadParam(final int sourceXSubsampling, final int sourceYSubsampling, final int subsamplingXOffset, - final int subsamplingYOffset, final Rectangle sourceRegion, final Dimension sourceRenderSize) { - this.canSetSourceRenderSize = true; - this.sourceRegion = sourceRegion; - this.sourceRenderSize = sourceRenderSize; - - if (sourceXSubsampling < 1 || sourceYSubsampling < 1) { - throw new IllegalArgumentException("Illegal subsampling factor: shall be 1 or greater; but was " - + " sourceXSubsampling=" + sourceXSubsampling + ", sourceYSubsampling=" + sourceYSubsampling); + public JBIG2ReadParam() + { + this(1, 1, 0, 0, null, null); } - setSourceSubsampling(sourceXSubsampling, sourceYSubsampling, subsamplingXOffset, subsamplingYOffset); - } + public JBIG2ReadParam(final int sourceXSubsampling, final int sourceYSubsampling, + final int subsamplingXOffset, final int subsamplingYOffset, + final Rectangle sourceRegion, final Dimension sourceRenderSize) + { + this.canSetSourceRenderSize = true; + this.sourceRegion = sourceRegion; + this.sourceRenderSize = sourceRenderSize; + + if (sourceXSubsampling < 1 || sourceYSubsampling < 1) + { + throw new IllegalArgumentException( + "Illegal subsampling factor: shall be 1 or greater; but was " + + " sourceXSubsampling=" + sourceXSubsampling + ", sourceYSubsampling=" + + sourceYSubsampling); + } + + setSourceSubsampling(sourceXSubsampling, sourceYSubsampling, subsamplingXOffset, + subsamplingYOffset); + } } http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/Region.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/Region.java b/src/main/java/org/apache/pdfbox/jbig2/Region.java index 87f431a..15366eb 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/Region.java +++ b/src/main/java/org/apache/pdfbox/jbig2/Region.java @@ -26,23 +26,25 @@ import org.apache.pdfbox.jbig2.segments.RegionSegmentInformation; /** * Interface for all JBIG2 region segments. */ -public interface Region extends SegmentData { +public interface Region extends SegmentData +{ - /** - * Decodes and returns a regions content. - * - * @return The decoded region as {@link Bitmap}. - * - * @throws IOException if an underlying IO operation fails - * @throws IntegerMaxValueException if the maximum value limit of an integer is exceeded - * @throws InvalidHeaderValueException if the segment header value is invalid - */ - public Bitmap getRegionBitmap() throws IOException, IntegerMaxValueException, InvalidHeaderValueException; + /** + * Decodes and returns a regions content. + * + * @return The decoded region as {@link Bitmap}. + * + * @throws IOException if an underlying IO operation fails + * @throws IntegerMaxValueException if the maximum value limit of an integer is exceeded + * @throws InvalidHeaderValueException if the segment header value is invalid + */ + public Bitmap getRegionBitmap() + throws IOException, IntegerMaxValueException, InvalidHeaderValueException; - /** - * Simply returns the {@link RegionSegmentInformation}. - * - * @return The {@link RegionSegmentInformation}. - */ - public RegionSegmentInformation getRegionInfo(); + /** + * Simply returns the {@link RegionSegmentInformation}. + * + * @return The {@link RegionSegmentInformation}. + */ + public RegionSegmentInformation getRegionInfo(); } http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/SegmentData.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/SegmentData.java b/src/main/java/org/apache/pdfbox/jbig2/SegmentData.java index d2aaef5..c5af68a 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/SegmentData.java +++ b/src/main/java/org/apache/pdfbox/jbig2/SegmentData.java @@ -26,18 +26,19 @@ import org.apache.pdfbox.jbig2.io.SubInputStream; /** * Interface for all data parts of segments. */ -public interface SegmentData { +public interface SegmentData +{ - /** - * Parse the stream and read information of header. - * - * @param header - The segments' header (to make referred-to segments available in data part). - * @param sis - Wrapped {@code ImageInputStream} into {@code SubInputStream}. - * - * @throws InvalidHeaderValueException if the segment header value is invalid - * @throws IntegerMaxValueException if the maximum value limit of an integer is exceeded - * @throws IOException if an underlying IO operation fails - */ - public void init(SegmentHeader header, SubInputStream sis) throws InvalidHeaderValueException, IntegerMaxValueException, - IOException; + /** + * Parse the stream and read information of header. + * + * @param header - The segments' header (to make referred-to segments available in data part). + * @param sis - Wrapped {@code ImageInputStream} into {@code SubInputStream}. + * + * @throws InvalidHeaderValueException if the segment header value is invalid + * @throws IntegerMaxValueException if the maximum value limit of an integer is exceeded + * @throws IOException if an underlying IO operation fails + */ + public void init(SegmentHeader header, SubInputStream sis) + throws InvalidHeaderValueException, IntegerMaxValueException, IOException; } http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/SegmentHeader.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/SegmentHeader.java b/src/main/java/org/apache/pdfbox/jbig2/SegmentHeader.java index c4e9cea..2cffbc7 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/SegmentHeader.java +++ b/src/main/java/org/apache/pdfbox/jbig2/SegmentHeader.java @@ -43,390 +43,415 @@ import org.apache.pdfbox.jbig2.util.log.LoggerFactory; * The basic class for all JBIG2 segments. */ @SuppressWarnings("unchecked") -public class SegmentHeader { - private static final Logger log = LoggerFactory.getLogger(SegmentHeader.class); +public class SegmentHeader +{ + private static final Logger log = LoggerFactory.getLogger(SegmentHeader.class); + + private static final Map<Integer, Class<? extends SegmentData>> SEGMENT_TYPE_MAP = new HashMap<Integer, Class<? extends SegmentData>>(); + + static + { + Object SEGMENT_TYPES[][] = { { 0, SymbolDictionary.class }, { 4, TextRegion.class }, + { 6, TextRegion.class }, { 7, TextRegion.class }, { 16, PatternDictionary.class }, + { 20, HalftoneRegion.class }, { 22, HalftoneRegion.class }, + { 23, HalftoneRegion.class }, { 36, GenericRegion.class }, + { 38, GenericRegion.class }, { 39, GenericRegion.class }, + { 40, GenericRefinementRegion.class }, { 42, GenericRefinementRegion.class }, + { 43, GenericRefinementRegion.class }, { 48, PageInformation.class }, + { 50, EndOfStripe.class }, { 52, Profiles.class }, { 53, Table.class }, }; + + for (int i = 0; i < SEGMENT_TYPES.length; i++) + { + Object[] objects = SEGMENT_TYPES[i]; + SEGMENT_TYPE_MAP.put((Integer) objects[0], (Class<? extends SegmentData>) objects[1]); + } + } + + private int segmentNr; + private int segmentType; + private byte retainFlag; + private int pageAssociation; + private byte pageAssociationFieldSize; + private SegmentHeader[] rtSegments; + private long segmentHeaderLength; + private long segmentDataLength; + private long segmentDataStartOffset; + private final SubInputStream subInputStream; + + private Reference<SegmentData> segmentData; + + public SegmentHeader(JBIG2Document document, SubInputStream sis, long offset, + int organisationType) throws IOException + { + this.subInputStream = sis; + parse(document, sis, offset, organisationType); + } + + /** + * + * + * @param document + * @param subInputStream + * @param organisationType + * @param offset - The offset where the segment header starts + * @throws IOException + */ + private void parse(JBIG2Document document, ImageInputStream subInputStream, long offset, + int organisationType) throws IOException + { + + printDebugMessage("\n########################"); + printDebugMessage("Segment parsing started."); + + subInputStream.seek(offset); + printDebugMessage("|-Seeked to offset: " + offset); + + /* 7.2.2 Segment number */ + readSegmentNumber(subInputStream); + + /* 7.2.3 Segment header flags */ + readSegmentHeaderFlag(subInputStream); - private static final Map<Integer, Class<? extends SegmentData>> SEGMENT_TYPE_MAP = new HashMap<Integer, Class<? extends SegmentData>>(); + /* 7.2.4 Amount of referred-to segments */ + int countOfRTS = readAmountOfReferredToSegments(subInputStream); + + /* 7.2.5 Referred-to segments numbers */ + int[] rtsNumbers = readReferredToSegmentsNumbers(subInputStream, countOfRTS); + + /* 7.2.6 Segment page association (Checks how big the page association field is.) */ + readSegmentPageAssociation(document, subInputStream, countOfRTS, rtsNumbers); + + /* 7.2.7 Segment data length (Contains the length of the data part (in bytes).) */ + readSegmentDataLength(subInputStream); + + readDataStartOffset(subInputStream, organisationType); + readSegmentHeaderLength(subInputStream, offset); + printDebugMessage("########################\n"); + } + + /** + * 7.2.2 Segment number + * + * @param subInputStream + * @throws IOException + */ + private void readSegmentNumber(ImageInputStream subInputStream) throws IOException + { + segmentNr = (int) (subInputStream.readBits(32) & 0xffffffff); + printDebugMessage("|-Segment Nr: " + segmentNr); + } + + /** + * 7.2.3 Segment header flags + * + * @param subInputStream + * @throws IOException + */ + private void readSegmentHeaderFlag(ImageInputStream subInputStream) throws IOException + { + // Bit 7: Retain Flag, if 1, this segment is flagged as retained; + retainFlag = (byte) subInputStream.readBit(); + printDebugMessage("|-Retain flag: " + retainFlag); + + // Bit 6: Size of the page association field. One byte if 0, four bytes if 1; + pageAssociationFieldSize = (byte) subInputStream.readBit(); + printDebugMessage("|-Page association field size=" + pageAssociationFieldSize); + + // Bit 5-0: Contains the values (between 0 and 62 with gaps) for segment types, specified in 7.3 + segmentType = (int) (subInputStream.readBits(6) & 0xff); + printDebugMessage("|-Segment type=" + segmentType); + } - static { - Object SEGMENT_TYPES[][] = { + /** + * 7.2.4 Amount of referred-to segments + * + * @param subInputStream + * @return The amount of referred-to segments. + * @throws IOException + */ + private int readAmountOfReferredToSegments(ImageInputStream subInputStream) throws IOException + { + int countOfRTS = (int) (subInputStream.readBits(3) & 0xf); + printDebugMessage("|-RTS count: " + countOfRTS); + + byte[] retainBit; + + printDebugMessage(" |-Stream position before RTS: " + subInputStream.getStreamPosition()); + + if (countOfRTS <= 4) + { + /* short format */ + retainBit = new byte[5]; + for (int i = 0; i <= 4; i++) + { + retainBit[i] = (byte) subInputStream.readBit(); + } + } + else { - 0, SymbolDictionary.class - }, { - 4, TextRegion.class - }, { - 6, TextRegion.class - }, { - 7, TextRegion.class - }, { - 16, PatternDictionary.class - }, { - 20, HalftoneRegion.class - }, { - 22, HalftoneRegion.class - }, { - 23, HalftoneRegion.class - }, { - 36, GenericRegion.class - }, { - 38, GenericRegion.class - }, { - 39, GenericRegion.class - }, { - 40, GenericRefinementRegion.class - }, { - 42, GenericRefinementRegion.class - }, { - 43, GenericRefinementRegion.class - }, { - 48, PageInformation.class - }, { - 50, EndOfStripe.class - }, { - 52, Profiles.class - }, { - 53, Table.class - }, - }; - - for (int i = 0; i < SEGMENT_TYPES.length; i++) { - Object[] objects = SEGMENT_TYPES[i]; - SEGMENT_TYPE_MAP.put((Integer) objects[0], (Class<? extends SegmentData>) objects[1]); + /* long format */ + countOfRTS = (int) (subInputStream.readBits(29) & 0xffffffff); + + int arrayLength = (countOfRTS + 8) >> 3; + retainBit = new byte[arrayLength <<= 3]; + + for (int i = 0; i < arrayLength; i++) + { + retainBit[i] = (byte) subInputStream.readBit(); + } + } + + printDebugMessage(" |-Stream position after RTS: " + subInputStream.getStreamPosition()); + + return countOfRTS; } - } - - private int segmentNr; - private int segmentType; - private byte retainFlag; - private int pageAssociation; - private byte pageAssociationFieldSize; - private SegmentHeader[] rtSegments; - private long segmentHeaderLength; - private long segmentDataLength; - private long segmentDataStartOffset; - private final SubInputStream subInputStream; - - private Reference<SegmentData> segmentData; - - - public SegmentHeader(JBIG2Document document, SubInputStream sis, long offset, int organisationType) - throws IOException { - this.subInputStream = sis; - parse(document, sis, offset, organisationType); - } - - /** - * - * - * @param document - * @param subInputStream - * @param organisationType - * @param offset - The offset where the segment header starts - * @throws IOException - */ - private void parse(JBIG2Document document, ImageInputStream subInputStream, long offset, int organisationType) - throws IOException { - - printDebugMessage("\n########################"); - printDebugMessage("Segment parsing started."); - - subInputStream.seek(offset); - printDebugMessage("|-Seeked to offset: " + offset); - - /* 7.2.2 Segment number */ - readSegmentNumber(subInputStream); - - /* 7.2.3 Segment header flags */ - readSegmentHeaderFlag(subInputStream); - - /* 7.2.4 Amount of referred-to segments */ - int countOfRTS = readAmountOfReferredToSegments(subInputStream); - - /* 7.2.5 Referred-to segments numbers */ - int[] rtsNumbers = readReferredToSegmentsNumbers(subInputStream, countOfRTS); - - /* 7.2.6 Segment page association (Checks how big the page association field is.) */ - readSegmentPageAssociation(document, subInputStream, countOfRTS, rtsNumbers); - - /* 7.2.7 Segment data length (Contains the length of the data part (in bytes).) */ - readSegmentDataLength(subInputStream); - - readDataStartOffset(subInputStream, organisationType); - readSegmentHeaderLength(subInputStream, offset); - printDebugMessage("########################\n"); - } - - /** - * 7.2.2 Segment number - * - * @param subInputStream - * @throws IOException - */ - private void readSegmentNumber(ImageInputStream subInputStream) throws IOException { - segmentNr = (int) (subInputStream.readBits(32) & 0xffffffff); - printDebugMessage("|-Segment Nr: " + segmentNr); - } - - /** - * 7.2.3 Segment header flags - * - * @param subInputStream - * @throws IOException - */ - private void readSegmentHeaderFlag(ImageInputStream subInputStream) throws IOException { - // Bit 7: Retain Flag, if 1, this segment is flagged as retained; - retainFlag = (byte) subInputStream.readBit(); - printDebugMessage("|-Retain flag: " + retainFlag); - - // Bit 6: Size of the page association field. One byte if 0, four bytes if 1; - pageAssociationFieldSize = (byte) subInputStream.readBit(); - printDebugMessage("|-Page association field size=" + pageAssociationFieldSize); - - // Bit 5-0: Contains the values (between 0 and 62 with gaps) for segment types, specified in 7.3 - segmentType = (int) (subInputStream.readBits(6) & 0xff); - printDebugMessage("|-Segment type=" + segmentType); - } - - /** - * 7.2.4 Amount of referred-to segments - * - * @param subInputStream - * @return The amount of referred-to segments. - * @throws IOException - */ - private int readAmountOfReferredToSegments(ImageInputStream subInputStream) throws IOException { - int countOfRTS = (int) (subInputStream.readBits(3) & 0xf); - printDebugMessage("|-RTS count: " + countOfRTS); - - byte[] retainBit; - - printDebugMessage(" |-Stream position before RTS: " + subInputStream.getStreamPosition()); - - if (countOfRTS <= 4) { - /* short format */ - retainBit = new byte[5]; - for (int i = 0; i <= 4; i++) { - retainBit[i] = (byte) subInputStream.readBit(); - } - } else { - /* long format */ - countOfRTS = (int) (subInputStream.readBits(29) & 0xffffffff); - - int arrayLength = (countOfRTS + 8) >> 3; - retainBit = new byte[arrayLength <<= 3]; - - for (int i = 0; i < arrayLength; i++) { - retainBit[i] = (byte) subInputStream.readBit(); - } + + /** + * 7.2.5 Referred-to segments numbers + * <p> + * Gathers all segment numbers of referred-to segments. The segments itself are stored in the {@link #rtSegments} + * array. + * + * @param subInputStream - Wrapped source data input stream. + * @param countOfRTS - The amount of referred-to segments. + * + * @return An array with the segment number of all referred-to segments. + * + * @throws IOException + */ + private int[] readReferredToSegmentsNumbers(ImageInputStream subInputStream, int countOfRTS) + throws IOException + { + int[] rtsNumbers = new int[countOfRTS]; + + if (countOfRTS > 0) + { + short rtsSize = 1; + if (segmentNr > 256) + { + rtsSize = 2; + if (segmentNr > 65536) + { + rtsSize = 4; + } + } + + rtSegments = new SegmentHeader[countOfRTS]; + + printDebugMessage("|-Length of RT segments list: " + rtSegments.length); + + for (int i = 0; i < countOfRTS; i++) + { + rtsNumbers[i] = (int) (subInputStream.readBits(rtsSize << 3) & 0xffffffff); + } + } + + return rtsNumbers; } - printDebugMessage(" |-Stream position after RTS: " + subInputStream.getStreamPosition()); - - return countOfRTS; - } - - /** - * 7.2.5 Referred-to segments numbers - * <p> - * Gathers all segment numbers of referred-to segments. The segments itself are stored in the - * {@link #rtSegments} array. - * - * @param subInputStream - Wrapped source data input stream. - * @param countOfRTS - The amount of referred-to segments. - * - * @return An array with the segment number of all referred-to segments. - * - * @throws IOException - */ - private int[] readReferredToSegmentsNumbers(ImageInputStream subInputStream, int countOfRTS) throws IOException { - int[] rtsNumbers = new int[countOfRTS]; - - if (countOfRTS > 0) { - short rtsSize = 1; - if (segmentNr > 256) { - rtsSize = 2; - if (segmentNr > 65536) { - rtsSize = 4; + /** + * 7.2.6 Segment page association + * + * @param document + * @param subInputStream + * @param countOfRTS + * @param rtsNumbers + * @throws IOException + */ + private void readSegmentPageAssociation(JBIG2Document document, ImageInputStream subInputStream, + int countOfRTS, int[] rtsNumbers) throws IOException + { + if (pageAssociationFieldSize == 0) + { + // Short format + pageAssociation = (short) (subInputStream.readBits(8) & 0xff); + } + else + { + // Long format + pageAssociation = (int) (subInputStream.readBits(32) & 0xffffffff); } - } - rtSegments = new SegmentHeader[countOfRTS]; + if (countOfRTS > 0) + { + final JBIG2Page page = document.getPage(pageAssociation); + for (int i = 0; i < countOfRTS; i++) + { + rtSegments[i] = (null != page ? page.getSegment(rtsNumbers[i]) + : document.getGlobalSegment(rtsNumbers[i])); + } + } + } - printDebugMessage("|-Length of RT segments list: " + rtSegments.length); + /** + * 7.2.7 Segment data length + * <p> + * Contains the length of the data part in bytes. + * + * @param subInputStream + * @throws IOException + */ + private void readSegmentDataLength(ImageInputStream subInputStream) throws IOException + { + segmentDataLength = (subInputStream.readBits(32) & 0xffffffff); + printDebugMessage("|-Data length: " + segmentDataLength); + } - for (int i = 0; i < countOfRTS; i++) { - rtsNumbers[i] = (int) (subInputStream.readBits(rtsSize << 3) & 0xffffffff); - } + /** + * Sets the offset only if organization type is SEQUENTIAL. If random, data starts after segment headers and can be + * determined when all segment headers are parsed and allocated. + * + * @param subInputStream + * @param organisationType + * @throws IOException + */ + private void readDataStartOffset(ImageInputStream subInputStream, int organisationType) + throws IOException + { + if (organisationType == JBIG2Document.SEQUENTIAL) + { + printDebugMessage("|-Organization is sequential."); + segmentDataStartOffset = subInputStream.getStreamPosition(); + } } - return rtsNumbers; - } - - /** - * 7.2.6 Segment page association - * - * @param document - * @param subInputStream - * @param countOfRTS - * @param rtsNumbers - * @throws IOException - */ - private void readSegmentPageAssociation(JBIG2Document document, ImageInputStream subInputStream, int countOfRTS, - int[] rtsNumbers) throws IOException { - if (pageAssociationFieldSize == 0) { - // Short format - pageAssociation = (short) (subInputStream.readBits(8) & 0xff); - } else { - // Long format - pageAssociation = (int) (subInputStream.readBits(32) & 0xffffffff); + private void readSegmentHeaderLength(ImageInputStream subInputStream, long offset) + throws IOException + { + segmentHeaderLength = subInputStream.getStreamPosition() - offset; + printDebugMessage("|-Segment header length: " + segmentHeaderLength); } - if (countOfRTS > 0) { - final JBIG2Page page = document.getPage(pageAssociation); - for (int i = 0; i < countOfRTS; i++) { - rtSegments[i] = (null != page ? page.getSegment(rtsNumbers[i]) : document.getGlobalSegment(rtsNumbers[i])); - } + private void printDebugMessage(String message) + { + log.debug(message); } - } - - /** - * 7.2.7 Segment data length - * <p> - * Contains the length of the data part in bytes. - * - * @param subInputStream - * @throws IOException - */ - private void readSegmentDataLength(ImageInputStream subInputStream) throws IOException { - segmentDataLength = (subInputStream.readBits(32) & 0xffffffff); - printDebugMessage("|-Data length: " + segmentDataLength); - } - - /** - * Sets the offset only if organization type is SEQUENTIAL. If random, data starts after segment - * headers and can be determined when all segment headers are parsed and allocated. - * - * @param subInputStream - * @param organisationType - * @throws IOException - */ - private void readDataStartOffset(ImageInputStream subInputStream, int organisationType) throws IOException { - if (organisationType == JBIG2Document.SEQUENTIAL) { - printDebugMessage("|-Organization is sequential."); - segmentDataStartOffset = subInputStream.getStreamPosition(); + + public int getSegmentNr() + { + return segmentNr; } - } - - private void readSegmentHeaderLength(ImageInputStream subInputStream, long offset) throws IOException { - segmentHeaderLength = subInputStream.getStreamPosition() - offset; - printDebugMessage("|-Segment header length: " + segmentHeaderLength); - } - - private void printDebugMessage(String message) { - log.debug(message); - } - - public int getSegmentNr() { - return segmentNr; - } - - public int getSegmentType() { - return segmentType; - } - - public long getSegmentHeaderLength() { - return segmentHeaderLength; - } - - public long getSegmentDataLength() { - return segmentDataLength; - } - - public long getSegmentDataStartOffset() { - return segmentDataStartOffset; - } - - public void setSegmentDataStartOffset(long segmentDataStartOffset) { - this.segmentDataStartOffset = segmentDataStartOffset; - } - - public SegmentHeader[] getRtSegments() { - return rtSegments; - } - - public int getPageAssociation() { - return pageAssociation; - } - - public short getRetainFlag() { - return retainFlag; - } - - /** - * Creates and returns a new {@link SubInputStream} that provides the data part of this segment. - * It is a clipped view of the source input stream. - * - * @return The {@link SubInputStream} that represents the data part of the segment. - */ - public SubInputStream getDataInputStream() { - return new SubInputStream(subInputStream, segmentDataStartOffset, segmentDataLength); - } - - /** - * Retrieves the segments' data part. - * - * @return Retrieved {@link SegmentData} instance. - */ - public SegmentData getSegmentData() { - SegmentData segmentDataPart = null; - - if (null != segmentData) { - segmentDataPart = segmentData.get(); + + public int getSegmentType() + { + return segmentType; } - if (null == segmentDataPart) { - try { + public long getSegmentHeaderLength() + { + return segmentHeaderLength; + } - Class<? extends SegmentData> segmentClass = SEGMENT_TYPE_MAP.get(segmentType); + public long getSegmentDataLength() + { + return segmentDataLength; + } - if (null == segmentClass) { - throw new IllegalArgumentException("No segment class for type " + segmentType); - } + public long getSegmentDataStartOffset() + { + return segmentDataStartOffset; + } - segmentDataPart = segmentClass.newInstance(); - segmentDataPart.init(this, getDataInputStream()); + public void setSegmentDataStartOffset(long segmentDataStartOffset) + { + this.segmentDataStartOffset = segmentDataStartOffset; + } - segmentData = new SoftReference<SegmentData>(segmentDataPart); + public SegmentHeader[] getRtSegments() + { + return rtSegments; + } - } catch (Exception e) { - throw new RuntimeException("Can't instantiate segment class", e); - } + public int getPageAssociation() + { + return pageAssociation; } - return segmentDataPart; - } + public short getRetainFlag() + { + return retainFlag; + } - public void cleanSegmentData() { - if (segmentData != null) { - segmentData = null; + /** + * Creates and returns a new {@link SubInputStream} that provides the data part of this segment. It is a clipped + * view of the source input stream. + * + * @return The {@link SubInputStream} that represents the data part of the segment. + */ + public SubInputStream getDataInputStream() + { + return new SubInputStream(subInputStream, segmentDataStartOffset, segmentDataLength); } - } - public String toString() { - StringBuilder stringBuilder = new StringBuilder(); + /** + * Retrieves the segments' data part. + * + * @return Retrieved {@link SegmentData} instance. + */ + public SegmentData getSegmentData() + { + SegmentData segmentDataPart = null; + + if (null != segmentData) + { + segmentDataPart = segmentData.get(); + } + + if (null == segmentDataPart) + { + try + { + + Class<? extends SegmentData> segmentClass = SEGMENT_TYPE_MAP.get(segmentType); + + if (null == segmentClass) + { + throw new IllegalArgumentException("No segment class for type " + segmentType); + } + + segmentDataPart = segmentClass.newInstance(); + segmentDataPart.init(this, getDataInputStream()); + + segmentData = new SoftReference<SegmentData>(segmentDataPart); + + } + catch (Exception e) + { + throw new RuntimeException("Can't instantiate segment class", e); + } + } + + return segmentDataPart; + } - if (rtSegments != null) { - for (SegmentHeader s : rtSegments) { - stringBuilder.append(s.segmentNr + " "); - } - } else { - stringBuilder.append("none"); + public void cleanSegmentData() + { + if (segmentData != null) + { + segmentData = null; + } } - return "\n#SegmentNr: " + segmentNr // - + "\n SegmentType: " + segmentType // - + "\n PageAssociation: " + pageAssociation // - + "\n Referred-to segments: " + stringBuilder.toString() // - + "\n"; // - } + public String toString() + { + StringBuilder stringBuilder = new StringBuilder(); + + if (rtSegments != null) + { + for (SegmentHeader s : rtSegments) + { + stringBuilder.append(s.segmentNr + " "); + } + } + else + { + stringBuilder.append("none"); + } + + return "\n#SegmentNr: " + segmentNr // + + "\n SegmentType: " + segmentType // + + "\n PageAssociation: " + pageAssociation // + + "\n Referred-to segments: " + stringBuilder.toString() // + + "\n"; // + } } http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/TestImage.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/TestImage.java b/src/main/java/org/apache/pdfbox/jbig2/TestImage.java index 10bb9c7..17b9d0d 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/TestImage.java +++ b/src/main/java/org/apache/pdfbox/jbig2/TestImage.java @@ -42,201 +42,224 @@ import javax.swing.JScrollPane; /** * This is a utility class. It can be used to show intermediary results. */ -public class TestImage extends JFrame { - private static final long serialVersionUID = 7353175320371957550L; - - public static void main(String[] args) { - int w = 250; - int h = 250; - - // (w+7) / 8 entspricht Aufrundung! - int scanlineStride = (w + 7) / 8; - - // hier sind die Daten - byte data[] = new byte[h * scanlineStride]; - - // dummy-Daten erzeugen - for (int i = 0; i < data.length; i++) - data[i] = (byte) i; - - new TestImage(data, w, h, scanlineStride); - } - - static class ImageComponent extends JComponent { - private static final long serialVersionUID = -5921296548288376287L; - Image myImage; - int imgWidth = -1; - int imgHeight = -1; - Dimension prefSize = null; - private int scale = 1; - - /** - * Constructor for ImageComponent. - */ - protected ImageComponent() { - super(); - } +public class TestImage extends JFrame +{ + private static final long serialVersionUID = 7353175320371957550L; - /** - * Constructor for ImageComponent. - */ - public ImageComponent(Image image) { - super(); - setImage(image); - } + public static void main(String[] args) + { + int w = 250; + int h = 250; - /** - * Gets the preffered Size of the Component - * - * @param image java.awt.Image - */ - public Dimension getPreferredSize() { - if (prefSize != null) - return this.prefSize; - else - return super.getPreferredSize(); - } + // (w+7) / 8 entspricht Aufrundung! + int scanlineStride = (w + 7) / 8; - /** - * Gets the minimum Size of the Component - * - * @param image java.awt.Image - */ - public Dimension getMinimumSize() { - if (prefSize != null) - return prefSize; - else - return super.getMinimumSize(); - } + // hier sind die Daten + byte data[] = new byte[h * scanlineStride]; - /** - * Sets an image to be shown - * - * @param image java.awt.Image - */ - public void setImage(Image image) { - if (myImage != null) { - myImage.flush(); - } + // dummy-Daten erzeugen + for (int i = 0; i < data.length; i++) + data[i] = (byte) i; - myImage = image; + new TestImage(data, w, h, scanlineStride); + } - if (myImage != null) { - MediaTracker mt = new MediaTracker(this); + static class ImageComponent extends JComponent + { + private static final long serialVersionUID = -5921296548288376287L; + Image myImage; + int imgWidth = -1; + int imgHeight = -1; + Dimension prefSize = null; + private int scale = 1; + + /** + * Constructor for ImageComponent. + */ + protected ImageComponent() + { + super(); + } - mt.addImage(myImage, 0); + /** + * Constructor for ImageComponent. + */ + public ImageComponent(Image image) + { + super(); + setImage(image); + } - try { - mt.waitForAll(); - } catch (Exception ex) { + /** + * Gets the preffered Size of the Component + * + * @param image java.awt.Image + */ + public Dimension getPreferredSize() + { + if (prefSize != null) + return this.prefSize; + else + return super.getPreferredSize(); } - imgWidth = myImage.getWidth(this); - imgHeight = myImage.getHeight(this); + /** + * Gets the minimum Size of the Component + * + * @param image java.awt.Image + */ + public Dimension getMinimumSize() + { + if (prefSize != null) + return prefSize; + else + return super.getMinimumSize(); + } - setSize(imgWidth * scale, imgHeight * scale); - prefSize = getSize(); - invalidate(); - validate(); - repaint(); - } - } + /** + * Sets an image to be shown + * + * @param image java.awt.Image + */ + public void setImage(Image image) + { + if (myImage != null) + { + myImage.flush(); + } + + myImage = image; + + if (myImage != null) + { + MediaTracker mt = new MediaTracker(this); + + mt.addImage(myImage, 0); + + try + { + mt.waitForAll(); + } + catch (Exception ex) + { + } + + imgWidth = myImage.getWidth(this); + imgHeight = myImage.getHeight(this); + + setSize(imgWidth * scale, imgHeight * scale); + prefSize = getSize(); + invalidate(); + validate(); + repaint(); + } + } - /** - * Get the Insets fo the Component - * - * @return Insets the Insets of the Component - */ - public Insets getInsets() { - return new Insets(1, 1, 1, 1); - } + /** + * Get the Insets fo the Component + * + * @return Insets the Insets of the Component + */ + public Insets getInsets() + { + return new Insets(1, 1, 1, 1); + } - /** - * Paints the component - * - * @param g java.awt.Graphics - */ - protected void paintComponent(Graphics g) { - Graphics2D g2 = (Graphics2D) g; - if (myImage != null) { - g2.scale(scale, scale); - g2.drawImage(myImage, 1, 1, imgWidth, imgHeight, this); - } - } + /** + * Paints the component + * + * @param g java.awt.Graphics + */ + protected void paintComponent(Graphics g) + { + Graphics2D g2 = (Graphics2D) g; + if (myImage != null) + { + g2.scale(scale, scale); + g2.drawImage(myImage, 1, 1, imgWidth, imgHeight, this); + } + } - public void setScale(int scale) { - this.scale = scale; + public void setScale(int scale) + { + this.scale = scale; - setSize(imgWidth * scale, imgHeight * scale); - prefSize = getSize(); + setSize(imgWidth * scale, imgHeight * scale); + prefSize = getSize(); - revalidate(); - repaint(); - } + revalidate(); + repaint(); + } - public int getScale() { - return scale; + public int getScale() + { + return scale; + } } - } - public TestImage(byte data[], int w, int h, int scanlineStride) { - super("Demobild"); + public TestImage(byte data[], int w, int h, int scanlineStride) + { + super("Demobild"); - // Color-Model sagt: bit = 0 -> schwarz, bit = 1 -> weiss. Ggf. umdrehen. - ColorModel colorModel = new IndexColorModel(1, 2, new byte[]{ - (byte) 0xff, 0x00 - }, new byte[]{ - (byte) 0xff, 0x00 - }, new byte[]{ - (byte) 0xff, 0x00 - }); + // Color-Model sagt: bit = 0 -> schwarz, bit = 1 -> weiss. Ggf. umdrehen. + ColorModel colorModel = new IndexColorModel(1, 2, new byte[] { (byte) 0xff, 0x00 }, + new byte[] { (byte) 0xff, 0x00 }, new byte[] { (byte) 0xff, 0x00 }); - DataBuffer dataBuffer = new DataBufferByte(data, data.length); - SampleModel sampleModel = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h, 1, scanlineStride, 0); - WritableRaster writableRaster = Raster.createWritableRaster(sampleModel, dataBuffer, new Point(0, 0)); + DataBuffer dataBuffer = new DataBufferByte(data, data.length); + SampleModel sampleModel = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h, 1, + scanlineStride, 0); + WritableRaster writableRaster = Raster.createWritableRaster(sampleModel, dataBuffer, + new Point(0, 0)); - BufferedImage image = new BufferedImage(colorModel, writableRaster, false, null); + BufferedImage image = new BufferedImage(colorModel, writableRaster, false, null); - ImageComponent imageComponent = new ImageComponent(image); - // imageComponent.setScale(4); + ImageComponent imageComponent = new ImageComponent(image); + // imageComponent.setScale(4); - JScrollPane sp = new JScrollPane(imageComponent); + JScrollPane sp = new JScrollPane(imageComponent); - setContentPane(sp); + setContentPane(sp); - pack(); - setSize(new Dimension(1600, 900)); - setVisible(true); + pack(); + setSize(new Dimension(1600, 900)); + setVisible(true); - try { - System.in.read(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + try + { + System.in.read(); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } } - } - public TestImage(BufferedImage bufferedImage) { - super("Demobild"); + public TestImage(BufferedImage bufferedImage) + { + super("Demobild"); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - ImageComponent imageComponent = new ImageComponent(bufferedImage); - imageComponent.setScale(1); + ImageComponent imageComponent = new ImageComponent(bufferedImage); + imageComponent.setScale(1); - JScrollPane sp = new JScrollPane(imageComponent); + JScrollPane sp = new JScrollPane(imageComponent); - setContentPane(sp); + setContentPane(sp); - pack(); - setSize(new Dimension(1600, 900)); - setVisible(true); + pack(); + setSize(new Dimension(1600, 900)); + setVisible(true); - try { - System.in.read(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + try + { + System.in.read(); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } } - } } http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoder.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoder.java b/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoder.java index b380afd..a520bd9 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoder.java +++ b/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticDecoder.java @@ -24,239 +24,191 @@ import javax.imageio.stream.ImageInputStream; /** * This class represents the arithmetic decoder, described in ISO/IEC 14492:2001 in E.3 */ -public class ArithmeticDecoder { - - private static final int QE[][] = { - { - 0x5601, 1, 1, 1 - }, { - 0x3401, 2, 6, 0 - }, { - 0x1801, 3, 9, 0 - }, { - 0x0AC1, 4, 12, 0 - }, { - 0x0521, 5, 29, 0 - }, { - 0x0221, 38, 33, 0 - }, { - 0x5601, 7, 6, 1 - }, { - 0x5401, 8, 14, 0 - }, { - 0x4801, 9, 14, 0 - }, { - 0x3801, 10, 14, 0 - }, { - 0x3001, 11, 17, 0 - }, { - 0x2401, 12, 18, 0 - }, { - 0x1C01, 13, 20, 0 - }, { - 0x1601, 29, 21, 0 - }, { - 0x5601, 15, 14, 1 - }, { - 0x5401, 16, 14, 0 - }, { - 0x5101, 17, 15, 0 - }, { - 0x4801, 18, 16, 0 - }, { - 0x3801, 19, 17, 0 - }, { - 0x3401, 20, 18, 0 - }, { - 0x3001, 21, 19, 0 - }, { - 0x2801, 22, 19, 0 - }, { - 0x2401, 23, 20, 0 - }, { - 0x2201, 24, 21, 0 - }, { - 0x1C01, 25, 22, 0 - }, { - 0x1801, 26, 23, 0 - }, { - 0x1601, 27, 24, 0 - }, { - 0x1401, 28, 25, 0 - }, { - 0x1201, 29, 26, 0 - }, { - 0x1101, 30, 27, 0 - }, { - 0x0AC1, 31, 28, 0 - }, { - 0x09C1, 32, 29, 0 - }, { - 0x08A1, 33, 30, 0 - }, { - 0x0521, 34, 31, 0 - }, { - 0x0441, 35, 32, 0 - }, { - 0x02A1, 36, 33, 0 - }, { - 0x0221, 37, 34, 0 - }, { - 0x0141, 38, 35, 0 - }, { - 0x0111, 39, 36, 0 - }, { - 0x0085, 40, 37, 0 - }, { - 0x0049, 41, 38, 0 - }, { - 0x0025, 42, 39, 0 - }, { - 0x0015, 43, 40, 0 - }, { - 0x0009, 44, 41, 0 - }, { - 0x0005, 45, 42, 0 - }, { - 0x0001, 45, 43, 0 - }, { - 0x5601, 46, 46, 0 - } - }; - - private int a; - private long c; - private int ct; - - private int b; - - private long streamPos0; - - private final ImageInputStream iis; - - public ArithmeticDecoder(ImageInputStream iis) throws IOException { - this.iis = iis; - init(); - } - - private void init() throws IOException { - this.streamPos0 = iis.getStreamPosition(); - b = this.iis.read(); - - c = b << 16; - - byteIn(); - - c <<= 7; - ct -= 7; - a = 0x8000; - } - - public int decode(CX cx) throws IOException { - int d; - final int qeValue = QE[cx.cx()][0]; - final int icx = cx.cx(); - - a -= qeValue; - - if ((c >> 16) < qeValue) { - d = lpsExchange(cx, icx, qeValue); - renormalize(); - } else { - c -= (qeValue << 16); - if ((a & 0x8000) == 0) { - d = mpsExchange(cx, icx); - renormalize(); - } else { - return cx.mps(); - } +public class ArithmeticDecoder +{ + + private static final int QE[][] = { { 0x5601, 1, 1, 1 }, { 0x3401, 2, 6, 0 }, + { 0x1801, 3, 9, 0 }, { 0x0AC1, 4, 12, 0 }, { 0x0521, 5, 29, 0 }, { 0x0221, 38, 33, 0 }, + { 0x5601, 7, 6, 1 }, { 0x5401, 8, 14, 0 }, { 0x4801, 9, 14, 0 }, { 0x3801, 10, 14, 0 }, + { 0x3001, 11, 17, 0 }, { 0x2401, 12, 18, 0 }, { 0x1C01, 13, 20, 0 }, + { 0x1601, 29, 21, 0 }, { 0x5601, 15, 14, 1 }, { 0x5401, 16, 14, 0 }, + { 0x5101, 17, 15, 0 }, { 0x4801, 18, 16, 0 }, { 0x3801, 19, 17, 0 }, + { 0x3401, 20, 18, 0 }, { 0x3001, 21, 19, 0 }, { 0x2801, 22, 19, 0 }, + { 0x2401, 23, 20, 0 }, { 0x2201, 24, 21, 0 }, { 0x1C01, 25, 22, 0 }, + { 0x1801, 26, 23, 0 }, { 0x1601, 27, 24, 0 }, { 0x1401, 28, 25, 0 }, + { 0x1201, 29, 26, 0 }, { 0x1101, 30, 27, 0 }, { 0x0AC1, 31, 28, 0 }, + { 0x09C1, 32, 29, 0 }, { 0x08A1, 33, 30, 0 }, { 0x0521, 34, 31, 0 }, + { 0x0441, 35, 32, 0 }, { 0x02A1, 36, 33, 0 }, { 0x0221, 37, 34, 0 }, + { 0x0141, 38, 35, 0 }, { 0x0111, 39, 36, 0 }, { 0x0085, 40, 37, 0 }, + { 0x0049, 41, 38, 0 }, { 0x0025, 42, 39, 0 }, { 0x0015, 43, 40, 0 }, + { 0x0009, 44, 41, 0 }, { 0x0005, 45, 42, 0 }, { 0x0001, 45, 43, 0 }, + { 0x5601, 46, 46, 0 } }; + + private int a; + private long c; + private int ct; + + private int b; + + private long streamPos0; + + private final ImageInputStream iis; + + public ArithmeticDecoder(ImageInputStream iis) throws IOException + { + this.iis = iis; + init(); } - return d; - } + private void init() throws IOException + { + this.streamPos0 = iis.getStreamPosition(); + b = this.iis.read(); - private void byteIn() throws IOException { - if (iis.getStreamPosition() > streamPos0) { - iis.seek(iis.getStreamPosition() - 1); - } - - b = iis.read(); - - if (b == 0xFF) { - final int b1 = iis.read(); - if (b1 > 0x8f) { - c += 0xff00; - ct = 8; - iis.seek(iis.getStreamPosition() - 2); - } else { - c += b1 << 9; - ct = 7; - } - } else { - b = iis.read(); - c += b << 8; - ct = 8; - } + c = b << 16; - c &= 0xffffffffL; - } - - private void renormalize() throws IOException { - do { - if (ct == 0) { byteIn(); - } - a <<= 1; - c <<= 1; - ct--; + c <<= 7; + ct -= 7; + a = 0x8000; + } - } while ((a & 0x8000) == 0); + public int decode(CX cx) throws IOException + { + int d; + final int qeValue = QE[cx.cx()][0]; + final int icx = cx.cx(); + + a -= qeValue; + + if ((c >> 16) < qeValue) + { + d = lpsExchange(cx, icx, qeValue); + renormalize(); + } + else + { + c -= (qeValue << 16); + if ((a & 0x8000) == 0) + { + d = mpsExchange(cx, icx); + renormalize(); + } + else + { + return cx.mps(); + } + } + + return d; + } - c &= 0xffffffffL; - } + private void byteIn() throws IOException + { + if (iis.getStreamPosition() > streamPos0) + { + iis.seek(iis.getStreamPosition() - 1); + } + + b = iis.read(); + + if (b == 0xFF) + { + final int b1 = iis.read(); + if (b1 > 0x8f) + { + c += 0xff00; + ct = 8; + iis.seek(iis.getStreamPosition() - 2); + } + else + { + c += b1 << 9; + ct = 7; + } + } + else + { + b = iis.read(); + c += b << 8; + ct = 8; + } + + c &= 0xffffffffL; + } - private int mpsExchange(CX cx, int icx) { - final int mps = cx.mps(); + private void renormalize() throws IOException + { + do + { + if (ct == 0) + { + byteIn(); + } - if (a < QE[icx][0]) { + a <<= 1; + c <<= 1; + ct--; - if (QE[icx][3] == 1) { - cx.toggleMps(); - } + } while ((a & 0x8000) == 0); - cx.setCx(QE[icx][2]); - return 1 - mps; - } else { - cx.setCx(QE[icx][1]); - return mps; + c &= 0xffffffffL; } - } - - private int lpsExchange(CX cx, int icx, int qeValue) { - final int mps = cx.mps(); - - if (a < qeValue) { - cx.setCx(QE[icx][1]); - a = qeValue; - return mps; - } else { - if (QE[icx][3] == 1) { - cx.toggleMps(); - } + private int mpsExchange(CX cx, int icx) + { + final int mps = cx.mps(); + + if (a < QE[icx][0]) + { + + if (QE[icx][3] == 1) + { + cx.toggleMps(); + } + + cx.setCx(QE[icx][2]); + return 1 - mps; + } + else + { + cx.setCx(QE[icx][1]); + return mps; + } + } - cx.setCx(QE[icx][2]); - a = qeValue; - return 1 - mps; + private int lpsExchange(CX cx, int icx, int qeValue) + { + final int mps = cx.mps(); + + if (a < qeValue) + { + cx.setCx(QE[icx][1]); + a = qeValue; + + return mps; + } + else + { + if (QE[icx][3] == 1) + { + cx.toggleMps(); + } + + cx.setCx(QE[icx][2]); + a = qeValue; + return 1 - mps; + } } - } - int getA() { - return a; - } + int getA() + { + return a; + } - long getC() { - return c; - } + long getC() + { + return c; + } } http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java b/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java index d4f1c99..8ef9b56 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java +++ b/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java @@ -22,135 +22,164 @@ import java.io.IOException; /** * This class represents the arithmetic integer decoder, described in ISO/IEC 14492:2001 (Annex A). */ -public class ArithmeticIntegerDecoder { +public class ArithmeticIntegerDecoder +{ - private final ArithmeticDecoder decoder; + private final ArithmeticDecoder decoder; - private int prev; + private int prev; - public ArithmeticIntegerDecoder(ArithmeticDecoder decoder) { - this.decoder = decoder; - } - - /** - * Arithmetic Integer Decoding Procedure, Annex A.2. - * - * @param cxIAx to be decoded value - * @return Decoded value. - * @throws IOException if an underlying IO operation fails - */ - public long decode(CX cxIAx) throws IOException { - int v = 0; - int d, s; - - int bitsToRead; - int offset; - - if (cxIAx == null) { - cxIAx = new CX(512, 1); + public ArithmeticIntegerDecoder(ArithmeticDecoder decoder) + { + this.decoder = decoder; } - prev = 1; - - cxIAx.setIndex(prev); - s = decoder.decode(cxIAx); - setPrev(s); + /** + * Arithmetic Integer Decoding Procedure, Annex A.2. + * + * @param cxIAx to be decoded value + * @return Decoded value. + * @throws IOException if an underlying IO operation fails + */ + public long decode(CX cxIAx) throws IOException + { + int v = 0; + int d, s; + + int bitsToRead; + int offset; + + if (cxIAx == null) + { + cxIAx = new CX(512, 1); + } - cxIAx.setIndex(prev); - d = decoder.decode(cxIAx); - setPrev(d); + prev = 1; - if (d == 1) { - cxIAx.setIndex(prev); - d = decoder.decode(cxIAx); - setPrev(d); + cxIAx.setIndex(prev); + s = decoder.decode(cxIAx); + setPrev(s); - if (d == 1) { cxIAx.setIndex(prev); d = decoder.decode(cxIAx); setPrev(d); - if (d == 1) { - cxIAx.setIndex(prev); - d = decoder.decode(cxIAx); - setPrev(d); - - if (d == 1) { + if (d == 1) + { cxIAx.setIndex(prev); d = decoder.decode(cxIAx); setPrev(d); - if (d == 1) { - bitsToRead = 32; - offset = 4436; - } else { - bitsToRead = 12; - offset = 340; + if (d == 1) + { + cxIAx.setIndex(prev); + d = decoder.decode(cxIAx); + setPrev(d); + + if (d == 1) + { + cxIAx.setIndex(prev); + d = decoder.decode(cxIAx); + setPrev(d); + + if (d == 1) + { + cxIAx.setIndex(prev); + d = decoder.decode(cxIAx); + setPrev(d); + + if (d == 1) + { + bitsToRead = 32; + offset = 4436; + } + else + { + bitsToRead = 12; + offset = 340; + } + } + else + { + bitsToRead = 8; + offset = 84; + } + } + else + { + bitsToRead = 6; + offset = 20; + } + } + else + { + bitsToRead = 4; + offset = 4; } - } else { - bitsToRead = 8; - offset = 84; - } - } else { - bitsToRead = 6; - offset = 20; } - } else { - bitsToRead = 4; - offset = 4; - } - } else { - bitsToRead = 2; - offset = 0; - } - - for (int i = 0; i < bitsToRead; i++) { - cxIAx.setIndex(prev); - d = decoder.decode(cxIAx); - setPrev(d); - v = (v << 1) | d; - } + else + { + bitsToRead = 2; + offset = 0; + } - v += offset; + for (int i = 0; i < bitsToRead; i++) + { + cxIAx.setIndex(prev); + d = decoder.decode(cxIAx); + setPrev(d); + v = (v << 1) | d; + } - if (s == 0) { - return v; - } else if (s == 1 && v > 0) { - return -v; - } + v += offset; - return Long.MAX_VALUE; - } + if (s == 0) + { + return v; + } + else if (s == 1 && v > 0) + { + return -v; + } - private void setPrev(int bit) { - if (prev < 256) { - prev = ((prev << 1) | bit) & 0x1ff; - } else { - prev = ((((prev << 1) | bit) & 511) | 256) & 0x1ff; + return Long.MAX_VALUE; } - } - - /** - * The IAID decoding procedure, Annex A.3. - * - * @param cxIAID - The contexts and statistics for decoding procedure. - * @param symCodeLen - Symbol code length. - * - * @return The decoded value. - * - * @throws IOException if an underlying IO operation fails - */ - public int decodeIAID(CX cxIAID, long symCodeLen) throws IOException { - // A.3 1) - prev = 1; - - // A.3 2) - for (int i = 0; i < symCodeLen; i++) { - cxIAID.setIndex(prev); - prev = (prev << 1) | decoder.decode(cxIAID); + + private void setPrev(int bit) + { + if (prev < 256) + { + prev = ((prev << 1) | bit) & 0x1ff; + } + else + { + prev = ((((prev << 1) | bit) & 511) | 256) & 0x1ff; + } } - // A.3 3) & 4) - return (prev - (1 << symCodeLen)); - } + /** + * The IAID decoding procedure, Annex A.3. + * + * @param cxIAID - The contexts and statistics for decoding procedure. + * @param symCodeLen - Symbol code length. + * + * @return The decoded value. + * + * @throws IOException if an underlying IO operation fails + */ + public int decodeIAID(CX cxIAID, long symCodeLen) throws IOException + { + // A.3 1) + prev = 1; + + // A.3 2) + for (int i = 0; i < symCodeLen; i++) + { + cxIAID.setIndex(prev); + prev = (prev << 1) | decoder.decode(cxIAID); + } + + // A.3 3) & 4) + return (prev - (1 << symCodeLen)); + } } http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/CX.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/CX.java b/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/CX.java index 6d03f58..adc5e60 100644 --- a/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/CX.java +++ b/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/CX.java @@ -18,52 +18,60 @@ package org.apache.pdfbox.jbig2.decoder.arithmetic; /** - * CX represents the context used by arithmetic decoding and arithmetic integer decoding. It selects - * the probability estimate and statistics used during decoding procedure. + * CX represents the context used by arithmetic decoding and arithmetic integer decoding. It selects the probability + * estimate and statistics used during decoding procedure. */ -public final class CX { - private int index; +public final class CX +{ + private int index; - private final byte cx[]; - private final byte mps[]; + private final byte cx[]; + private final byte mps[]; - /** - * @param size - Amount of context values. - * @param index - Start index. - */ - public CX(int size, int index) { - this.index = index; - cx = new byte[size]; - mps = new byte[size]; - } + /** + * @param size - Amount of context values. + * @param index - Start index. + */ + public CX(int size, int index) + { + this.index = index; + cx = new byte[size]; + mps = new byte[size]; + } - protected int cx() { - return cx[index] & 0x7f; - } + protected int cx() + { + return cx[index] & 0x7f; + } - protected void setCx(int value) { - cx[index] = (byte) (value & 0x7f); - } + protected void setCx(int value) + { + cx[index] = (byte) (value & 0x7f); + } - /** - * @return The decision. Possible values are {@code 0} or {@code 1}. - */ - protected byte mps() { - return mps[index]; - } + /** + * @return The decision. Possible values are {@code 0} or {@code 1}. + */ + protected byte mps() + { + return mps[index]; + } - /** - * Flips the bit in actual "more predictable symbol" array element. - */ - protected void toggleMps() { - mps[index] ^= 1; - } + /** + * Flips the bit in actual "more predictable symbol" array element. + */ + protected void toggleMps() + { + mps[index] ^= 1; + } - protected int getIndex() { - return index; - } + protected int getIndex() + { + return index; + } - public void setIndex(int index) { - this.index = index; - } + public void setIndex(int index) + { + this.index = index; + } }