http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressor.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressor.java 
b/src/main/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressor.java
index b1ab753..84e2f08 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressor.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/decoder/mmr/MMRDecompressor.java
@@ -28,585 +28,691 @@ import org.apache.pdfbox.jbig2.Bitmap;
 /**
  * A decompressor for MMR compression.
  */
-public class MMRDecompressor {
-
-  private int width;
-  private int height;
-
-  /**
-   * A class encapsulating the compressed raw data.
-   */
-  private final class RunData {
-    private static final int MAX_RUN_DATA_BUFFER = 1024 << 7; // 1024 * 128
-    private static final int MIN_RUN_DATA_BUFFER = 3; // min. bytes to 
decompress
-    private static final int CODE_OFFSET = 24;
-
-    /** Compressed data stream. */
-    ImageInputStream stream;
-
-    int offset;
-    int lastOffset = 0;
-    int lastCode = 0;
-
-    byte buffer[];
-    int bufferBase;
-    int bufferTop;
-
-    RunData(ImageInputStream stream) {
-      this.stream = stream;
-      offset = 0;
-      lastOffset = 1;
-
-      try {
-        long len = stream.length();
-
-        len = Math.min(Math.max(MIN_RUN_DATA_BUFFER, len), 
MAX_RUN_DATA_BUFFER);
-
-        buffer = new byte[(int) len];
-        fillBuffer(0);
-      } catch (IOException e) {
-        buffer = new byte[10];
-        e.printStackTrace();
-      }
-    }
+public class MMRDecompressor
+{
 
-    private final Code uncompressGetCode(Code table[]) {
-      return uncompressGetCodeLittleEndian(table);
-    }
+    private int width;
+    private int height;
 
-    private final Code uncompressGetCodeLittleEndian(Code table[]) {
-      final int code = uncompressGetNextCodeLittleEndian() & 0xffffff;
-      Code result = table[code >> CODE_OFFSET - FIRST_LEVEL_TABLE_SIZE];
+    /**
+     * A class encapsulating the compressed raw data.
+     */
+    private final class RunData
+    {
+        private static final int MAX_RUN_DATA_BUFFER = 1024 << 7; // 1024 * 128
+        private static final int MIN_RUN_DATA_BUFFER = 3; // min. bytes to 
decompress
+        private static final int CODE_OFFSET = 24;
 
-      // perform second-level lookup
-      if (null != result && null != result.subTable) {
-        result = result.subTable[(code >> CODE_OFFSET - FIRST_LEVEL_TABLE_SIZE 
- SECOND_LEVEL_TABLE_SIZE)
-            & SECOND_LEVEL_TABLE_MASK];
-      }
+        /** Compressed data stream. */
+        ImageInputStream stream;
 
-      return result;
-    }
+        int offset;
+        int lastOffset = 0;
+        int lastCode = 0;
 
-    /**
-     * Fill up the code word in little endian mode. This is a hotspot, 
therefore the algorithm is
-     * heavily optimised. For the frequent cases (i.e. short words) we try to 
get away with as
-     * little work as possible. <br>
-     * This method returns code words of 16 bits, which are aligned to the 
24th bit. The lowest 8
-     * bits are used as a "queue" of bits so that an access to the actual data 
is only needed, when
-     * this queue becomes empty.
-     */
-    private final int uncompressGetNextCodeLittleEndian() {
-      try {
-
-        // the number of bits to fill (offset difference)
-        int bitsToFill = offset - lastOffset;
-
-        // check whether we can refill, or need to fill in absolute mode
-        if (bitsToFill < 0 || bitsToFill > 24) {
-          // refill at absolute offset
-          int byteOffset = (offset >> 3) - bufferBase; // offset>>3 is 
equivalent to offset/8
-
-          if (byteOffset >= bufferTop) {
-            byteOffset += bufferBase;
-            fillBuffer(byteOffset);
-            byteOffset -= bufferBase;
-          }
-
-          lastCode = (buffer[byteOffset] & 0xff) << 16 | (buffer[byteOffset + 
1] & 0xff) << 8
-              | (buffer[byteOffset + 2] & 0xff);
-
-          int bitOffset = offset & 7; // equivalent to offset%8
-          lastCode <<= bitOffset;
-        } else {
-          // the offset to the next byte boundary as seen from the last offset
-          int bitOffset = lastOffset & 7;
-          final int avail = 7 - bitOffset;
-
-          // check whether there are enough bits in the "queue"
-          if (bitsToFill <= avail) {
-            lastCode <<= bitsToFill;
-          } else {
-            int byteOffset = (lastOffset >> 3) + 3 - bufferBase;
-
-            if (byteOffset >= bufferTop) {
-              byteOffset += bufferBase;
-              fillBuffer(byteOffset);
-              byteOffset -= bufferBase;
-            }
+        byte buffer[];
+        int bufferBase;
+        int bufferTop;
 
-            bitOffset = 8 - bitOffset;
-            do {
-              lastCode <<= bitOffset;
-              lastCode |= buffer[byteOffset] & 0xff;
-              bitsToFill -= bitOffset;
-              byteOffset++;
-              bitOffset = 8;
-            } while (bitsToFill >= 8);
-
-            lastCode <<= bitsToFill; // shift the rest
-          }
-        }
-        lastOffset = offset;
-
-        return lastCode;
-      } catch (IOException e) {
-        // will this actually happen? only with broken data, I'd say.
-        throw new ArrayIndexOutOfBoundsException("Corrupted RLE data caused by 
an IOException while reading raw data: "
-            + e.toString());
-      }
-    }
+        RunData(ImageInputStream stream)
+        {
+            this.stream = stream;
+            offset = 0;
+            lastOffset = 1;
 
-    private void fillBuffer(int byteOffset) throws IOException {
-      bufferBase = byteOffset;
-      synchronized (stream) {
-        try {
-          stream.seek(byteOffset);
-          bufferTop = stream.read(buffer);
-        } catch (EOFException e) {
-          // you never know which kind of EOF will kick in
-          bufferTop = -1;
-        }
-        // check filling degree
-        if (bufferTop > -1 && bufferTop < 3) {
-          // CK: if filling degree is too small,
-          // smoothly fill up to the next three bytes or substitute with with
-          // empty bytes
-          int read = 0;
-          while (bufferTop < 3) {
-            try {
-              read = stream.read();
-            } catch (EOFException e) {
-              read = -1;
+            try
+            {
+                long len = stream.length();
+
+                len = Math.min(Math.max(MIN_RUN_DATA_BUFFER, len), 
MAX_RUN_DATA_BUFFER);
+
+                buffer = new byte[(int) len];
+                fillBuffer(0);
+            }
+            catch (IOException e)
+            {
+                buffer = new byte[10];
+                e.printStackTrace();
             }
-            buffer[bufferTop++] = read == -1 ? 0 : (byte) (read & 0xff);
-          }
         }
-      }
-      // leave some room, in order to save a few tests in the calling code
-      bufferTop -= 3;
-
-      if (bufferTop < 0) {
-        // if we're at EOF, just supply zero-bytes
-        Arrays.fill(buffer, (byte) 0);
-        bufferTop = buffer.length - 3;
-      }
-    }
 
-    /**
-     * Skip to next byte
-     */
-    private void align() {
-      offset = ((offset + 7) >> 3) << 3;
-    }
-  }
+        private final Code uncompressGetCode(Code table[])
+        {
+            return uncompressGetCodeLittleEndian(table);
+        }
 
-  private static final class Code {
-    Code subTable[] = null;
+        private final Code uncompressGetCodeLittleEndian(Code table[])
+        {
+            final int code = uncompressGetNextCodeLittleEndian() & 0xffffff;
+            Code result = table[code >> CODE_OFFSET - FIRST_LEVEL_TABLE_SIZE];
 
-    final int bitLength, codeWord, runLength;
+            // perform second-level lookup
+            if (null != result && null != result.subTable)
+            {
+                result = result.subTable[(code >> CODE_OFFSET - 
FIRST_LEVEL_TABLE_SIZE
+                        - SECOND_LEVEL_TABLE_SIZE) & SECOND_LEVEL_TABLE_MASK];
+            }
 
-    Code(int codeData[]) {
-      bitLength = codeData[0];
-      codeWord = codeData[1];
-      runLength = codeData[2];
-    }
+            return result;
+        }
 
-    public String toString() {
-      return bitLength + "/" + codeWord + "/" + runLength;
-    }
+        /**
+         * Fill up the code word in little endian mode. This is a hotspot, 
therefore the algorithm is heavily optimised.
+         * For the frequent cases (i.e. short words) we try to get away with 
as little work as possible. <br>
+         * This method returns code words of 16 bits, which are aligned to the 
24th bit. The lowest 8 bits are used as a
+         * "queue" of bits so that an access to the actual data is only 
needed, when this queue becomes empty.
+         */
+        private final int uncompressGetNextCodeLittleEndian()
+        {
+            try
+            {
+
+                // the number of bits to fill (offset difference)
+                int bitsToFill = offset - lastOffset;
+
+                // check whether we can refill, or need to fill in absolute 
mode
+                if (bitsToFill < 0 || bitsToFill > 24)
+                {
+                    // refill at absolute offset
+                    int byteOffset = (offset >> 3) - bufferBase; // offset>>3 
is equivalent to offset/8
+
+                    if (byteOffset >= bufferTop)
+                    {
+                        byteOffset += bufferBase;
+                        fillBuffer(byteOffset);
+                        byteOffset -= bufferBase;
+                    }
+
+                    lastCode = (buffer[byteOffset] & 0xff) << 16
+                            | (buffer[byteOffset + 1] & 0xff) << 8
+                            | (buffer[byteOffset + 2] & 0xff);
+
+                    int bitOffset = offset & 7; // equivalent to offset%8
+                    lastCode <<= bitOffset;
+                }
+                else
+                {
+                    // the offset to the next byte boundary as seen from the 
last offset
+                    int bitOffset = lastOffset & 7;
+                    final int avail = 7 - bitOffset;
+
+                    // check whether there are enough bits in the "queue"
+                    if (bitsToFill <= avail)
+                    {
+                        lastCode <<= bitsToFill;
+                    }
+                    else
+                    {
+                        int byteOffset = (lastOffset >> 3) + 3 - bufferBase;
+
+                        if (byteOffset >= bufferTop)
+                        {
+                            byteOffset += bufferBase;
+                            fillBuffer(byteOffset);
+                            byteOffset -= bufferBase;
+                        }
+
+                        bitOffset = 8 - bitOffset;
+                        do
+                        {
+                            lastCode <<= bitOffset;
+                            lastCode |= buffer[byteOffset] & 0xff;
+                            bitsToFill -= bitOffset;
+                            byteOffset++;
+                            bitOffset = 8;
+                        } while (bitsToFill >= 8);
+
+                        lastCode <<= bitsToFill; // shift the rest
+                    }
+                }
+                lastOffset = offset;
 
-    /**
-     * @see java.lang.Object#equals(Object)
-     */
-    public boolean equals(Object obj) {
-      return (obj instanceof Code) && //
-          ((Code) obj).bitLength == bitLength && //
-          ((Code) obj).codeWord == codeWord && //
-          ((Code) obj).runLength == runLength;
-    }
-  }
+                return lastCode;
+            }
+            catch (IOException e)
+            {
+                // will this actually happen? only with broken data, I'd say.
+                throw new ArrayIndexOutOfBoundsException(
+                        "Corrupted RLE data caused by an IOException while 
reading raw data: "
+                                + e.toString());
+            }
+        }
 
-  private static final int FIRST_LEVEL_TABLE_SIZE = 8;
-  private static final int FIRST_LEVEL_TABLE_MASK = (1 << 
FIRST_LEVEL_TABLE_SIZE) - 1;
-  private static final int SECOND_LEVEL_TABLE_SIZE = 5;
-  private static final int SECOND_LEVEL_TABLE_MASK = (1 << 
SECOND_LEVEL_TABLE_SIZE) - 1;
+        private void fillBuffer(int byteOffset) throws IOException
+        {
+            bufferBase = byteOffset;
+            synchronized (stream)
+            {
+                try
+                {
+                    stream.seek(byteOffset);
+                    bufferTop = stream.read(buffer);
+                }
+                catch (EOFException e)
+                {
+                    // you never know which kind of EOF will kick in
+                    bufferTop = -1;
+                }
+                // check filling degree
+                if (bufferTop > -1 && bufferTop < 3)
+                {
+                    // CK: if filling degree is too small,
+                    // smoothly fill up to the next three bytes or substitute 
with with
+                    // empty bytes
+                    int read = 0;
+                    while (bufferTop < 3)
+                    {
+                        try
+                        {
+                            read = stream.read();
+                        }
+                        catch (EOFException e)
+                        {
+                            read = -1;
+                        }
+                        buffer[bufferTop++] = read == -1 ? 0 : (byte) (read & 
0xff);
+                    }
+                }
+            }
+            // leave some room, in order to save a few tests in the calling 
code
+            bufferTop -= 3;
+
+            if (bufferTop < 0)
+            {
+                // if we're at EOF, just supply zero-bytes
+                Arrays.fill(buffer, (byte) 0);
+                bufferTop = buffer.length - 3;
+            }
+        }
 
-  private static Code whiteTable[] = null;
-  private static Code blackTable[] = null;
-  private static Code modeTable[] = null;
+        /**
+         * Skip to next byte
+         */
+        private void align()
+        {
+            offset = ((offset + 7) >> 3) << 3;
+        }
+    }
 
-  private RunData data;
+    private static final class Code
+    {
+        Code subTable[] = null;
 
-  private synchronized final static void initTables() {
-    if (null == whiteTable) {
-      whiteTable = createLittleEndianTable(MMRConstants.WhiteCodes);
-      blackTable = createLittleEndianTable(MMRConstants.BlackCodes);
-      modeTable = createLittleEndianTable(MMRConstants.ModeCodes);
-    }
-  }
+        final int bitLength, codeWord, runLength;
 
-  private final int uncompress2D(RunData runData, int[] referenceOffsets, int 
refRunLength, int[] runOffsets, int width) {
+        Code(int codeData[])
+        {
+            bitLength = codeData[0];
+            codeWord = codeData[1];
+            runLength = codeData[2];
+        }
 
-    int referenceBufferOffset = 0;
-    int currentBufferOffset = 0;
-    int currentLineBitPosition = 0;
+        public String toString()
+        {
+            return bitLength + "/" + codeWord + "/" + runLength;
+        }
 
-    boolean whiteRun = true; // Always start with a white run
-    Code code = null; // Storage var for current code being processed
+        /**
+         * @see java.lang.Object#equals(Object)
+         */
+        public boolean equals(Object obj)
+        {
+            return (obj instanceof Code) && //
+                    ((Code) obj).bitLength == bitLength && //
+                    ((Code) obj).codeWord == codeWord && //
+                    ((Code) obj).runLength == runLength;
+        }
+    }
 
-    referenceOffsets[refRunLength] = referenceOffsets[refRunLength + 1] = 
width;
-    referenceOffsets[refRunLength + 2] = referenceOffsets[refRunLength + 3] = 
width + 1;
+    private static final int FIRST_LEVEL_TABLE_SIZE = 8;
+    private static final int FIRST_LEVEL_TABLE_MASK = (1 << 
FIRST_LEVEL_TABLE_SIZE) - 1;
+    private static final int SECOND_LEVEL_TABLE_SIZE = 5;
+    private static final int SECOND_LEVEL_TABLE_MASK = (1 << 
SECOND_LEVEL_TABLE_SIZE) - 1;
 
-    try {
-      decodeLoop : while (currentLineBitPosition < width) {
+    private static Code whiteTable[] = null;
+    private static Code blackTable[] = null;
+    private static Code modeTable[] = null;
 
-        // Get the mode code
-        code = runData.uncompressGetCode(modeTable);
+    private RunData data;
 
-        if (code == null) {
-          runData.offset++;
-          break decodeLoop;
+    private synchronized final static void initTables()
+    {
+        if (null == whiteTable)
+        {
+            whiteTable = createLittleEndianTable(MMRConstants.WhiteCodes);
+            blackTable = createLittleEndianTable(MMRConstants.BlackCodes);
+            modeTable = createLittleEndianTable(MMRConstants.ModeCodes);
         }
+    }
 
-        // Add the code length to the bit offset
-        runData.offset += code.bitLength;
-
-        switch (code.runLength){
-          case MMRConstants.CODE_V0 :
-            currentLineBitPosition = referenceOffsets[referenceBufferOffset];
-            break;
+    private final int uncompress2D(RunData runData, int[] referenceOffsets, 
int refRunLength,
+            int[] runOffsets, int width)
+    {
 
-          case MMRConstants.CODE_VR1 :
-            currentLineBitPosition = referenceOffsets[referenceBufferOffset] + 
1;
-            break;
+        int referenceBufferOffset = 0;
+        int currentBufferOffset = 0;
+        int currentLineBitPosition = 0;
 
-          case MMRConstants.CODE_VL1 :
-            currentLineBitPosition = referenceOffsets[referenceBufferOffset] - 
1;
-            break;
+        boolean whiteRun = true; // Always start with a white run
+        Code code = null; // Storage var for current code being processed
 
-          case MMRConstants.CODE_H :
-            for (int ever = 1; ever > 0;) {
+        referenceOffsets[refRunLength] = referenceOffsets[refRunLength + 1] = 
width;
+        referenceOffsets[refRunLength + 2] = referenceOffsets[refRunLength + 
3] = width + 1;
 
-              code = runData.uncompressGetCode(whiteRun == true ? whiteTable : 
blackTable);
+        try
+        {
+            decodeLoop: while (currentLineBitPosition < width)
+            {
 
-              if (code == null)
-                break decodeLoop;
+                // Get the mode code
+                code = runData.uncompressGetCode(modeTable);
 
-              runData.offset += code.bitLength;
-              if (code.runLength < 64) {
-                if (code.runLength < 0) {
-                  runOffsets[currentBufferOffset++] = currentLineBitPosition;
-                  code = null;
-                  break decodeLoop;
+                if (code == null)
+                {
+                    runData.offset++;
+                    break decodeLoop;
                 }
-                currentLineBitPosition += code.runLength;
-                runOffsets[currentBufferOffset++] = currentLineBitPosition;
-                break;
-              }
-              currentLineBitPosition += code.runLength;
-            }
 
-            final int firstHalfBitPos = currentLineBitPosition;
-            for (int ever1 = 1; ever1 > 0;) {
-              code = runData.uncompressGetCode(whiteRun != true ? whiteTable : 
blackTable);
-              if (code == null)
-                break decodeLoop;
-
-              runData.offset += code.bitLength;
-              if (code.runLength < 64) {
-                if (code.runLength < 0) {
-                  runOffsets[currentBufferOffset++] = currentLineBitPosition;
-                  break decodeLoop;
+                // Add the code length to the bit offset
+                runData.offset += code.bitLength;
+
+                switch (code.runLength)
+                {
+                case MMRConstants.CODE_V0:
+                    currentLineBitPosition = 
referenceOffsets[referenceBufferOffset];
+                    break;
+
+                case MMRConstants.CODE_VR1:
+                    currentLineBitPosition = 
referenceOffsets[referenceBufferOffset] + 1;
+                    break;
+
+                case MMRConstants.CODE_VL1:
+                    currentLineBitPosition = 
referenceOffsets[referenceBufferOffset] - 1;
+                    break;
+
+                case MMRConstants.CODE_H:
+                    for (int ever = 1; ever > 0;)
+                    {
+
+                        code = runData
+                                .uncompressGetCode(whiteRun == true ? 
whiteTable : blackTable);
+
+                        if (code == null)
+                            break decodeLoop;
+
+                        runData.offset += code.bitLength;
+                        if (code.runLength < 64)
+                        {
+                            if (code.runLength < 0)
+                            {
+                                runOffsets[currentBufferOffset++] = 
currentLineBitPosition;
+                                code = null;
+                                break decodeLoop;
+                            }
+                            currentLineBitPosition += code.runLength;
+                            runOffsets[currentBufferOffset++] = 
currentLineBitPosition;
+                            break;
+                        }
+                        currentLineBitPosition += code.runLength;
+                    }
+
+                    final int firstHalfBitPos = currentLineBitPosition;
+                    for (int ever1 = 1; ever1 > 0;)
+                    {
+                        code = runData
+                                .uncompressGetCode(whiteRun != true ? 
whiteTable : blackTable);
+                        if (code == null)
+                            break decodeLoop;
+
+                        runData.offset += code.bitLength;
+                        if (code.runLength < 64)
+                        {
+                            if (code.runLength < 0)
+                            {
+                                runOffsets[currentBufferOffset++] = 
currentLineBitPosition;
+                                break decodeLoop;
+                            }
+                            currentLineBitPosition += code.runLength;
+                            // don't generate 0-length run at EOL for cases 
where the line ends in an H-run.
+                            if (currentLineBitPosition < width
+                                    || currentLineBitPosition != 
firstHalfBitPos)
+                                runOffsets[currentBufferOffset++] = 
currentLineBitPosition;
+                            break;
+                        }
+                        currentLineBitPosition += code.runLength;
+                    }
+
+                    while (currentLineBitPosition < width
+                            && referenceOffsets[referenceBufferOffset] <= 
currentLineBitPosition)
+                    {
+                        referenceBufferOffset += 2;
+                    }
+                    continue decodeLoop;
+
+                case MMRConstants.CODE_P:
+                    referenceBufferOffset++;
+                    currentLineBitPosition = 
referenceOffsets[referenceBufferOffset++];
+                    continue decodeLoop;
+
+                case MMRConstants.CODE_VR2:
+                    currentLineBitPosition = 
referenceOffsets[referenceBufferOffset] + 2;
+                    break;
+
+                case MMRConstants.CODE_VL2:
+                    currentLineBitPosition = 
referenceOffsets[referenceBufferOffset] - 2;
+                    break;
+
+                case MMRConstants.CODE_VR3:
+                    currentLineBitPosition = 
referenceOffsets[referenceBufferOffset] + 3;
+                    break;
+
+                case MMRConstants.CODE_VL3:
+                    currentLineBitPosition = 
referenceOffsets[referenceBufferOffset] - 3;
+                    break;
+
+                case MMRConstants.EOL:
+                default:
+                    System.err.println("Should not happen!");
+                    // Possibly MMR Decoded
+                    if (runData.offset == 12 && code.runLength == 
MMRConstants.EOL)
+                    {
+                        runData.offset = 0;
+                        uncompress1D(runData, referenceOffsets, width);
+                        runData.offset++;
+                        uncompress1D(runData, runOffsets, width);
+                        int retCode = uncompress1D(runData, referenceOffsets, 
width);
+                        runData.offset++;
+                        return retCode;
+                    }
+                    currentLineBitPosition = width;
+                    continue decodeLoop;
                 }
-                currentLineBitPosition += code.runLength;
-                // don't generate 0-length run at EOL for cases where the line 
ends in an H-run.
-                if (currentLineBitPosition < width || currentLineBitPosition 
!= firstHalfBitPos)
-                  runOffsets[currentBufferOffset++] = currentLineBitPosition;
-                break;
-              }
-              currentLineBitPosition += code.runLength;
-            }
 
-            while (currentLineBitPosition < width && 
referenceOffsets[referenceBufferOffset] <= currentLineBitPosition) {
-              referenceBufferOffset += 2;
-            }
-            continue decodeLoop;
-
-          case MMRConstants.CODE_P :
-            referenceBufferOffset++;
-            currentLineBitPosition = referenceOffsets[referenceBufferOffset++];
-            continue decodeLoop;
-
-          case MMRConstants.CODE_VR2 :
-            currentLineBitPosition = referenceOffsets[referenceBufferOffset] + 
2;
-            break;
-
-          case MMRConstants.CODE_VL2 :
-            currentLineBitPosition = referenceOffsets[referenceBufferOffset] - 
2;
-            break;
-
-          case MMRConstants.CODE_VR3 :
-            currentLineBitPosition = referenceOffsets[referenceBufferOffset] + 
3;
-            break;
-
-          case MMRConstants.CODE_VL3 :
-            currentLineBitPosition = referenceOffsets[referenceBufferOffset] - 
3;
-            break;
-
-          case MMRConstants.EOL :
-          default :
-            System.err.println("Should not happen!");
-            // Possibly MMR Decoded
-            if (runData.offset == 12 && code.runLength == MMRConstants.EOL) {
-              runData.offset = 0;
-              uncompress1D(runData, referenceOffsets, width);
-              runData.offset++;
-              uncompress1D(runData, runOffsets, width);
-              int retCode = uncompress1D(runData, referenceOffsets, width);
-              runData.offset++;
-              return retCode;
+                // Only vertical modes get this far
+                if (currentLineBitPosition <= width)
+                {
+                    whiteRun = !whiteRun;
+
+                    runOffsets[currentBufferOffset++] = currentLineBitPosition;
+
+                    if (referenceBufferOffset > 0)
+                    {
+                        referenceBufferOffset--;
+                    }
+                    else
+                    {
+                        referenceBufferOffset++;
+                    }
+
+                    while (currentLineBitPosition < width
+                            && referenceOffsets[referenceBufferOffset] <= 
currentLineBitPosition)
+                    {
+                        referenceBufferOffset += 2;
+                    }
+                }
             }
-            currentLineBitPosition = width;
-            continue decodeLoop;
+        }
+        catch (Throwable t)
+        {
+            StringBuffer strBuf = new StringBuffer();
+            strBuf.append("whiteRun           = ");
+            strBuf.append(whiteRun);
+            strBuf.append("\n");
+            strBuf.append("code               = ");
+            strBuf.append(code);
+            strBuf.append("\n");
+            strBuf.append("refOffset          = ");
+            strBuf.append(referenceBufferOffset);
+            strBuf.append("\n");
+            strBuf.append("curOffset          = ");
+            strBuf.append(currentBufferOffset);
+            strBuf.append("\n");
+            strBuf.append("bitPos             = ");
+            strBuf.append(currentLineBitPosition);
+            strBuf.append("\n");
+            strBuf.append("runData.offset = ");
+            strBuf.append(runData.offset);
+            strBuf.append(" ( byte:");
+            strBuf.append(runData.offset / 8);
+            strBuf.append(", bit:");
+            strBuf.append(runData.offset & 0x07);
+            strBuf.append(" )");
+
+            System.out.println(strBuf.toString());
+
+            return MMRConstants.EOF;
         }
 
-        // Only vertical modes get this far
-        if (currentLineBitPosition <= width) {
-          whiteRun = !whiteRun;
-
-          runOffsets[currentBufferOffset++] = currentLineBitPosition;
-
-          if (referenceBufferOffset > 0) {
-            referenceBufferOffset--;
-          } else {
-            referenceBufferOffset++;
-          }
+        if (runOffsets[currentBufferOffset] != width)
+        {
+            runOffsets[currentBufferOffset] = width;
+        }
 
-          while (currentLineBitPosition < width && 
referenceOffsets[referenceBufferOffset] <= currentLineBitPosition) {
-            referenceBufferOffset += 2;
-          }
+        if (code == null)
+        {
+            return MMRConstants.EOL;
         }
-      }
-    } catch (Throwable t) {
-      StringBuffer strBuf = new StringBuffer();
-      strBuf.append("whiteRun           = ");
-      strBuf.append(whiteRun);
-      strBuf.append("\n");
-      strBuf.append("code               = ");
-      strBuf.append(code);
-      strBuf.append("\n");
-      strBuf.append("refOffset          = ");
-      strBuf.append(referenceBufferOffset);
-      strBuf.append("\n");
-      strBuf.append("curOffset          = ");
-      strBuf.append(currentBufferOffset);
-      strBuf.append("\n");
-      strBuf.append("bitPos             = ");
-      strBuf.append(currentLineBitPosition);
-      strBuf.append("\n");
-      strBuf.append("runData.offset = ");
-      strBuf.append(runData.offset);
-      strBuf.append(" ( byte:");
-      strBuf.append(runData.offset / 8);
-      strBuf.append(", bit:");
-      strBuf.append(runData.offset & 0x07);
-      strBuf.append(" )");
-
-      System.out.println(strBuf.toString());
-
-      return MMRConstants.EOF;
+        return currentBufferOffset;
     }
 
-    if (runOffsets[currentBufferOffset] != width) {
-      runOffsets[currentBufferOffset] = width;
-    }
+    public MMRDecompressor(int width, int height, ImageInputStream stream)
+    {
+        this.width = width;
+        this.height = height;
+
+        data = new RunData(stream);
 
-    if (code == null) {
-      return MMRConstants.EOL;
+        initTables();
     }
-    return currentBufferOffset;
-  }
 
-  public MMRDecompressor(int width, int height, ImageInputStream stream) {
-    this.width = width;
-    this.height = height;
+    public Bitmap uncompress()
+    {
+        final Bitmap result = new Bitmap(width, height);
 
-    data = new RunData(stream);
+        int[] currentOffsets = new int[width + 5];
+        int[] referenceOffsets = new int[width + 5];
+        referenceOffsets[0] = width;
+        int refRunLength = 1;
 
-    initTables();
-  }
+        int count = 0;
 
-  public Bitmap uncompress() {
-    final Bitmap result = new Bitmap(width, height);
+        for (int line = 0; line < height; line++)
+        {
+            count = uncompress2D(data, referenceOffsets, refRunLength, 
currentOffsets, width);
 
-    int[] currentOffsets = new int[width + 5];
-    int[] referenceOffsets = new int[width + 5];
-    referenceOffsets[0] = width;
-    int refRunLength = 1;
+            if (count == MMRConstants.EOF)
+            {
+                break;
+            }
 
-    int count = 0;
+            if (count > 0)
+            {
+                fillBitmap(result, line, currentOffsets, count);
+            }
 
-    for (int line = 0; line < height; line++) {
-      count = uncompress2D(data, referenceOffsets, refRunLength, 
currentOffsets, width);
+            // Swap lines
+            int tempOffsets[] = referenceOffsets;
+            referenceOffsets = currentOffsets;
+            currentOffsets = tempOffsets;
+            refRunLength = count;
+        }
 
-      if (count == MMRConstants.EOF) {
-        break;
-      }
+        detectAndSkipEOL();
 
-      if (count > 0) {
-        fillBitmap(result, line, currentOffsets, count);
-      }
+        data.align();
 
-      // Swap lines
-      int tempOffsets[] = referenceOffsets;
-      referenceOffsets = currentOffsets;
-      currentOffsets = tempOffsets;
-      refRunLength = count;
+        return result;
     }
 
-    detectAndSkipEOL();
-
-    data.align();
-
-    return result;
-  }
-
-  private void detectAndSkipEOL() {
-    while (true) {
-      Code code = data.uncompressGetCode(modeTable);
-      if (null != code && code.runLength == MMRConstants.EOL) {
-        data.offset += code.bitLength;
-      } else
-        break;
+    private void detectAndSkipEOL()
+    {
+        while (true)
+        {
+            Code code = data.uncompressGetCode(modeTable);
+            if (null != code && code.runLength == MMRConstants.EOL)
+            {
+                data.offset += code.bitLength;
+            }
+            else
+                break;
+        }
     }
-  }
 
-  private void fillBitmap(Bitmap result, int line, int[] currentOffsets, int 
count) {
+    private void fillBitmap(Bitmap result, int line, int[] currentOffsets, int 
count)
+    {
 
-    int x = 0;
-    int targetByte = result.getByteIndex(0, line);
-    byte targetByteValue = 0;
-    for (int index = 0; index < count; index++) {
+        int x = 0;
+        int targetByte = result.getByteIndex(0, line);
+        byte targetByteValue = 0;
+        for (int index = 0; index < count; index++)
+        {
 
-      final int offset = currentOffsets[index];
-      byte value;
+            final int offset = currentOffsets[index];
+            byte value;
 
-      if ((index & 1) == 0) {
-        value = 0;
-      } else {
-        value = 1;
-      }
+            if ((index & 1) == 0)
+            {
+                value = 0;
+            }
+            else
+            {
+                value = 1;
+            }
 
-      while (x < offset) {
-        targetByteValue = (byte) ((targetByteValue << 1) | value);
-        x++;
+            while (x < offset)
+            {
+                targetByteValue = (byte) ((targetByteValue << 1) | value);
+                x++;
 
-        if ((x & 7) == 0) {
-          result.setByte(targetByte++, targetByteValue);
-          targetByteValue = 0;
+                if ((x & 7) == 0)
+                {
+                    result.setByte(targetByte++, targetByteValue);
+                    targetByteValue = 0;
+                }
+            }
         }
-      }
-    }
 
-    if ((x & 7) != 0) {
-      targetByteValue <<= 8 - (x & 7);
-      result.setByte(targetByte, targetByteValue);
+        if ((x & 7) != 0)
+        {
+            targetByteValue <<= 8 - (x & 7);
+            result.setByte(targetByte, targetByteValue);
+        }
     }
-  }
 
-  private final int uncompress1D(RunData runData, int[] runOffsets, int width) 
{
+    private final int uncompress1D(RunData runData, int[] runOffsets, int 
width)
+    {
+
+        boolean whiteRun = true;
+        int iBitPos = 0;
+        Code code = null;
+        int refOffset = 0;
+
+        loop: while (iBitPos < width)
+        {
+            while (true)
+            {
+                if (whiteRun)
+                {
+                    code = runData.uncompressGetCode(whiteTable);
+                }
+                else
+                {
+                    code = runData.uncompressGetCode(blackTable);
+                }
 
-    boolean whiteRun = true;
-    int iBitPos = 0;
-    Code code = null;
-    int refOffset = 0;
+                runData.offset += code.bitLength;
 
-    loop : while (iBitPos < width) {
-      while (true) {
-        if (whiteRun) {
-          code = runData.uncompressGetCode(whiteTable);
-        } else {
-          code = runData.uncompressGetCode(blackTable);
-        }
+                if (code.runLength < 0)
+                {
+                    break loop;
+                }
 
-        runData.offset += code.bitLength;
+                iBitPos += code.runLength;
 
-        if (code.runLength < 0) {
-          break loop;
+                if (code.runLength < 64)
+                {
+                    whiteRun = !whiteRun;
+                    runOffsets[refOffset++] = iBitPos;
+                    break;
+                }
+            }
         }
 
-        iBitPos += code.runLength;
-
-        if (code.runLength < 64) {
-          whiteRun = !whiteRun;
-          runOffsets[refOffset++] = iBitPos;
-          break;
+        if (runOffsets[refOffset] != width)
+        {
+            runOffsets[refOffset] = width;
         }
-      }
-    }
 
-    if (runOffsets[refOffset] != width) {
-      runOffsets[refOffset] = width;
+        return code != null && code.runLength != MMRConstants.EOL ? refOffset 
: MMRConstants.EOL;
     }
 
-    return code != null && code.runLength != MMRConstants.EOL ? refOffset : 
MMRConstants.EOL;
-  }
-
-  /**
-   * For little endian, the tables are structured like this:
-   * 
-   * <pre>
-   *  v--------v length = FIRST_LEVEL_TABLE_LENGTH
-   *                v-----v length = SECOND_LEVEL_TABLE_LENGTH
-   * 
-   *  A code word which fits into the first level table (length=3)
-   *  [Cccvvvvv]
-   * 
-   *  A code word which needs the second level table also (length=10)
-   *  [Cccccccc] -&gt; [ccvvv]
-   * 
-   *  &quot;C&quot; denotes the first code word bit
-   *  &quot;c&quot; denotes a code word bit
-   *  &quot;v&quot; denotes a variant bit
-   * </pre>
-   * 
-   */
-  private static Code[] createLittleEndianTable(int codes[][]) {
-    final Code firstLevelTable[] = new Code[FIRST_LEVEL_TABLE_MASK + 1];
-    for (int i = 0; i < codes.length; i++) {
-      final Code code = new Code(codes[i]);
-
-      if (code.bitLength <= FIRST_LEVEL_TABLE_SIZE) {
-        final int variantLength = FIRST_LEVEL_TABLE_SIZE - code.bitLength;
-        final int baseWord = code.codeWord << variantLength;
-
-        for (int variant = (1 << variantLength) - 1; variant >= 0; variant--) {
-          final int index = baseWord | variant;
-          firstLevelTable[index] = code;
-        }
-      } else {
-        // init second level table
-        final int firstLevelIndex = code.codeWord >>> code.bitLength - 
FIRST_LEVEL_TABLE_SIZE;
-
-        if (firstLevelTable[firstLevelIndex] == null) {
-          final Code firstLevelCode = new Code(new int[3]);
-          firstLevelCode.subTable = new Code[SECOND_LEVEL_TABLE_MASK + 1];
-          firstLevelTable[firstLevelIndex] = firstLevelCode;
-        }
+    /**
+     * For little endian, the tables are structured like this:
+     * 
+     * <pre>
+     *  v--------v length = FIRST_LEVEL_TABLE_LENGTH
+     *                v-----v length = SECOND_LEVEL_TABLE_LENGTH
+     * 
+     *  A code word which fits into the first level table (length=3)
+     *  [Cccvvvvv]
+     * 
+     *  A code word which needs the second level table also (length=10)
+     *  [Cccccccc] -&gt; [ccvvv]
+     * 
+     *  &quot;C&quot; denotes the first code word bit
+     *  &quot;c&quot; denotes a code word bit
+     *  &quot;v&quot; denotes a variant bit
+     * </pre>
+     * 
+     */
+    private static Code[] createLittleEndianTable(int codes[][])
+    {
+        final Code firstLevelTable[] = new Code[FIRST_LEVEL_TABLE_MASK + 1];
+        for (int i = 0; i < codes.length; i++)
+        {
+            final Code code = new Code(codes[i]);
+
+            if (code.bitLength <= FIRST_LEVEL_TABLE_SIZE)
+            {
+                final int variantLength = FIRST_LEVEL_TABLE_SIZE - 
code.bitLength;
+                final int baseWord = code.codeWord << variantLength;
+
+                for (int variant = (1 << variantLength) - 1; variant >= 0; 
variant--)
+                {
+                    final int index = baseWord | variant;
+                    firstLevelTable[index] = code;
+                }
+            }
+            else
+            {
+                // init second level table
+                final int firstLevelIndex = code.codeWord >>> code.bitLength
+                        - FIRST_LEVEL_TABLE_SIZE;
+
+                if (firstLevelTable[firstLevelIndex] == null)
+                {
+                    final Code firstLevelCode = new Code(new int[3]);
+                    firstLevelCode.subTable = new Code[SECOND_LEVEL_TABLE_MASK 
+ 1];
+                    firstLevelTable[firstLevelIndex] = firstLevelCode;
+                }
 
-        // fill second level table
-        if (code.bitLength <= FIRST_LEVEL_TABLE_SIZE + 
SECOND_LEVEL_TABLE_SIZE) {
-          final Code secondLevelTable[] = 
firstLevelTable[firstLevelIndex].subTable;
-          final int variantLength = FIRST_LEVEL_TABLE_SIZE + 
SECOND_LEVEL_TABLE_SIZE - code.bitLength;
-          final int baseWord = (code.codeWord << variantLength) & 
SECOND_LEVEL_TABLE_MASK;
-
-          for (int variant = (1 << variantLength) - 1; variant >= 0; 
variant--) {
-            secondLevelTable[baseWord | variant] = code;
-          }
-        } else
-          throw new IllegalArgumentException("Code table overflow in 
MMRDecompressor");
-      }
+                // fill second level table
+                if (code.bitLength <= FIRST_LEVEL_TABLE_SIZE + 
SECOND_LEVEL_TABLE_SIZE)
+                {
+                    final Code secondLevelTable[] = 
firstLevelTable[firstLevelIndex].subTable;
+                    final int variantLength = FIRST_LEVEL_TABLE_SIZE + 
SECOND_LEVEL_TABLE_SIZE
+                            - code.bitLength;
+                    final int baseWord = (code.codeWord << variantLength) & 
SECOND_LEVEL_TABLE_MASK;
+
+                    for (int variant = (1 << variantLength) - 1; variant >= 0; 
variant--)
+                    {
+                        secondLevelTable[baseWord | variant] = code;
+                    }
+                }
+                else
+                    throw new IllegalArgumentException("Code table overflow in 
MMRDecompressor");
+            }
+        }
+        return firstLevelTable;
     }
-    return firstLevelTable;
-  }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/err/IntegerMaxValueException.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/pdfbox/jbig2/err/IntegerMaxValueException.java 
b/src/main/java/org/apache/pdfbox/jbig2/err/IntegerMaxValueException.java
index 3f1b479..5477dd7 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/err/IntegerMaxValueException.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/err/IntegerMaxValueException.java
@@ -20,23 +20,28 @@ package org.apache.pdfbox.jbig2.err;
 /**
  * Can be used if the maximum value limit of an integer is exceeded.
  */
-public class IntegerMaxValueException extends JBIG2Exception {
+public class IntegerMaxValueException extends JBIG2Exception
+{
 
-  private static final long serialVersionUID = -5534202639860867867L;
+    private static final long serialVersionUID = -5534202639860867867L;
 
-  public IntegerMaxValueException() {
-  }
+    public IntegerMaxValueException()
+    {
+    }
 
-  public IntegerMaxValueException(String message) {
-    super(message);
-  }
+    public IntegerMaxValueException(String message)
+    {
+        super(message);
+    }
 
-  public IntegerMaxValueException(Throwable cause) {
-    super(cause);
-  }
+    public IntegerMaxValueException(Throwable cause)
+    {
+        super(cause);
+    }
 
-  public IntegerMaxValueException(String message, Throwable cause) {
-    super(message, cause);
-  }
+    public IntegerMaxValueException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/err/InvalidHeaderValueException.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/pdfbox/jbig2/err/InvalidHeaderValueException.java 
b/src/main/java/org/apache/pdfbox/jbig2/err/InvalidHeaderValueException.java
index c1ed069..ccca43d 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/err/InvalidHeaderValueException.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/err/InvalidHeaderValueException.java
@@ -20,23 +20,28 @@ package org.apache.pdfbox.jbig2.err;
 /**
  * Can be used if a segment header value is invalid.
  */
-public class InvalidHeaderValueException extends JBIG2Exception {
+public class InvalidHeaderValueException extends JBIG2Exception
+{
 
-  private static final long serialVersionUID = -5534202639860867867L;
+    private static final long serialVersionUID = -5534202639860867867L;
 
-  public InvalidHeaderValueException() {
-  }
+    public InvalidHeaderValueException()
+    {
+    }
 
-  public InvalidHeaderValueException(String message) {
-    super(message);
-  }
+    public InvalidHeaderValueException(String message)
+    {
+        super(message);
+    }
 
-  public InvalidHeaderValueException(Throwable cause) {
-    super(cause);
-  }
+    public InvalidHeaderValueException(Throwable cause)
+    {
+        super(cause);
+    }
 
-  public InvalidHeaderValueException(String message, Throwable cause) {
-    super(message, cause);
-  }
+    public InvalidHeaderValueException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/err/JBIG2Exception.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/err/JBIG2Exception.java 
b/src/main/java/org/apache/pdfbox/jbig2/err/JBIG2Exception.java
index 2a53fe1..4a8579a 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/err/JBIG2Exception.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/err/JBIG2Exception.java
@@ -20,23 +20,28 @@ package org.apache.pdfbox.jbig2.err;
 /**
  * Identifies a JBIG2 exception.
  */
-public class JBIG2Exception extends Exception {
+public class JBIG2Exception extends Exception
+{
 
-  private static final long serialVersionUID = 5063673874564442169L;
+    private static final long serialVersionUID = 5063673874564442169L;
 
-  public JBIG2Exception() {
-  }
+    public JBIG2Exception()
+    {
+    }
 
-  public JBIG2Exception(String message) {
-    super(message);
-  }
+    public JBIG2Exception(String message)
+    {
+        super(message);
+    }
 
-  public JBIG2Exception(Throwable cause) {
-    super(cause);
-  }
+    public JBIG2Exception(Throwable cause)
+    {
+        super(cause);
+    }
 
-  public JBIG2Exception(String message, Throwable cause) {
-    super(message, cause);
-  }
+    public JBIG2Exception(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/BitmapScanline.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/BitmapScanline.java 
b/src/main/java/org/apache/pdfbox/jbig2/image/BitmapScanline.java
index 1babb59..4fdb5f4 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/BitmapScanline.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/BitmapScanline.java
@@ -21,107 +21,128 @@ import java.awt.image.WritableRaster;
 
 import org.apache.pdfbox.jbig2.Bitmap;
 
-final class BitmapScanline extends Scanline {
-
-  private Bitmap bitmap;
-  private WritableRaster raster;
-
-  private int[] lineBuffer;
-
-  public BitmapScanline(final Bitmap src, final WritableRaster dst, final int 
width) {
-    super(width);
-    this.bitmap = src;
-    this.raster = dst;
-    lineBuffer = new int[length];
-  }
-
-  @Override
-  protected void clear() {
-    lineBuffer = new int[length];
-  }
-
-  @Override
-  protected void fetch(int x, final int y) {
-    lineBuffer = new int[length]; // really required?
-    int srcByteIdx = bitmap.getByteIndex(x, y);
-    while (x < length) {
-      final byte srcByte = (byte) ~bitmap.getByte(srcByteIdx++);
-      final int bits = bitmap.getWidth() - x > 8 ? 8 : bitmap.getWidth() - x;
-      for (int bitPosition = bits - 1; bitPosition >= 0; bitPosition--, x++) {
-        if (((srcByte >> bitPosition) & 0x1) != 0)
-          lineBuffer[x] = 255;
-      }
+final class BitmapScanline extends Scanline
+{
+
+    private Bitmap bitmap;
+    private WritableRaster raster;
+
+    private int[] lineBuffer;
+
+    public BitmapScanline(final Bitmap src, final WritableRaster dst, final 
int width)
+    {
+        super(width);
+        this.bitmap = src;
+        this.raster = dst;
+        lineBuffer = new int[length];
+    }
+
+    @Override
+    protected void clear()
+    {
+        lineBuffer = new int[length];
     }
-  }
-
-  @Override
-  protected void filter(final int[] preShift, final int[] postShift, final 
Weighttab[] tabs, final Scanline dst) {
-    final BitmapScanline dstBitmapScanline = (BitmapScanline) dst;
-    final int dstLength = dst.length;
-
-    // start sum at 1 << shift - 1 for rounding
-    final int start = 1 << postShift[0] - 1;
-    final int srcBuffer[] = lineBuffer;
-    final int dstBuffer[] = dstBitmapScanline.lineBuffer;
-
-    // the next two blocks are duplicated except for the missing shift 
operation if preShift == 0.
-    final int preShift0 = preShift[0];
-    final int postShift0 = postShift[0];
-    if (preShift0 != 0) {
-      for (int dstIndex = 0, tab = 0; tab < dstLength; tab++) {
-        final Weighttab weightTab = tabs[tab];
-        final int weights = weightTab.weights.length;
-
-        int sum = start;
-        for (int weightIndex = 0, srcIndex = weightTab.i0; weightIndex < 
weights && srcIndex < srcBuffer.length; weightIndex++) {
-          sum += weightTab.weights[weightIndex] * (srcBuffer[srcIndex++] >> 
preShift0);
-        }
 
-        final int t = sum >> postShift0;
-        dstBuffer[dstIndex++] = t < 0 ? 0 : t > 255 ? 255 : t;
-      }
-    } else {
-      for (int dstIndex = 0, tab = 0; tab < dstLength; tab++) {
-        final Weighttab weightTab = tabs[tab];
-        final int weights = weightTab.weights.length;
-
-        int sum = start;
-        for (int weightIndex = 0, srcIndex = weightTab.i0; weightIndex < 
weights && srcIndex < srcBuffer.length; weightIndex++) {
-          sum += weightTab.weights[weightIndex] * srcBuffer[srcIndex++];
+    @Override
+    protected void fetch(int x, final int y)
+    {
+        lineBuffer = new int[length]; // really required?
+        int srcByteIdx = bitmap.getByteIndex(x, y);
+        while (x < length)
+        {
+            final byte srcByte = (byte) ~bitmap.getByte(srcByteIdx++);
+            final int bits = bitmap.getWidth() - x > 8 ? 8 : bitmap.getWidth() 
- x;
+            for (int bitPosition = bits - 1; bitPosition >= 0; bitPosition--, 
x++)
+            {
+                if (((srcByte >> bitPosition) & 0x1) != 0)
+                    lineBuffer[x] = 255;
+            }
         }
+    }
 
-        dstBuffer[dstIndex++] = sum >> postShift0;
-      }
+    @Override
+    protected void filter(final int[] preShift, final int[] postShift, final 
Weighttab[] tabs,
+            final Scanline dst)
+    {
+        final BitmapScanline dstBitmapScanline = (BitmapScanline) dst;
+        final int dstLength = dst.length;
+
+        // start sum at 1 << shift - 1 for rounding
+        final int start = 1 << postShift[0] - 1;
+        final int srcBuffer[] = lineBuffer;
+        final int dstBuffer[] = dstBitmapScanline.lineBuffer;
+
+        // the next two blocks are duplicated except for the missing shift 
operation if preShift == 0.
+        final int preShift0 = preShift[0];
+        final int postShift0 = postShift[0];
+        if (preShift0 != 0)
+        {
+            for (int dstIndex = 0, tab = 0; tab < dstLength; tab++)
+            {
+                final Weighttab weightTab = tabs[tab];
+                final int weights = weightTab.weights.length;
+
+                int sum = start;
+                for (int weightIndex = 0, srcIndex = weightTab.i0; weightIndex 
< weights
+                        && srcIndex < srcBuffer.length; weightIndex++)
+                {
+                    sum += weightTab.weights[weightIndex] * 
(srcBuffer[srcIndex++] >> preShift0);
+                }
+
+                final int t = sum >> postShift0;
+                dstBuffer[dstIndex++] = t < 0 ? 0 : t > 255 ? 255 : t;
+            }
+        }
+        else
+        {
+            for (int dstIndex = 0, tab = 0; tab < dstLength; tab++)
+            {
+                final Weighttab weightTab = tabs[tab];
+                final int weights = weightTab.weights.length;
+
+                int sum = start;
+                for (int weightIndex = 0, srcIndex = weightTab.i0; weightIndex 
< weights
+                        && srcIndex < srcBuffer.length; weightIndex++)
+                {
+                    sum += weightTab.weights[weightIndex] * 
srcBuffer[srcIndex++];
+                }
+
+                dstBuffer[dstIndex++] = sum >> postShift0;
+            }
+        }
     }
-  }
 
-  @Override
-  protected void accumulate(final int weight, final Scanline dst) {
-    final BitmapScanline dstBitmapScanline = (BitmapScanline) dst;
+    @Override
+    protected void accumulate(final int weight, final Scanline dst)
+    {
+        final BitmapScanline dstBitmapScanline = (BitmapScanline) dst;
 
-    final int srcBuffer[] = lineBuffer;
-    final int dstBuffer[] = dstBitmapScanline.lineBuffer;
+        final int srcBuffer[] = lineBuffer;
+        final int dstBuffer[] = dstBitmapScanline.lineBuffer;
 
-    for (int b = 0; b < dstBuffer.length; b++)
-      dstBuffer[b] += weight * srcBuffer[b];
-  }
+        for (int b = 0; b < dstBuffer.length; b++)
+            dstBuffer[b] += weight * srcBuffer[b];
+    }
 
-  @Override
-  protected void shift(final int[] shift) {
-    final int shift0 = shift[0];
-    final int half = 1 << shift0 - 1;
+    @Override
+    protected void shift(final int[] shift)
+    {
+        final int shift0 = shift[0];
+        final int half = 1 << shift0 - 1;
 
-    final int srcBuffer[] = lineBuffer;
+        final int srcBuffer[] = lineBuffer;
 
-    for (int b = 0; b < srcBuffer.length; b++) {
-      final int pixel = srcBuffer[b] + half >> shift0;
-      srcBuffer[b] = pixel < 0 ? 0 : pixel > 255 ? 255 : pixel;
+        for (int b = 0; b < srcBuffer.length; b++)
+        {
+            final int pixel = srcBuffer[b] + half >> shift0;
+            srcBuffer[b] = pixel < 0 ? 0 : pixel > 255 ? 255 : pixel;
+        }
     }
-  }
 
-  @Override
-  protected void store(final int x, final int y) {
-    raster.setSamples(x, y, length, 1, 0, lineBuffer);
-  }
+    @Override
+    protected void store(final int x, final int y)
+    {
+        raster.setSamples(x, y, length, 1, 0, lineBuffer);
+    }
 
-}
\ No newline at end of file
+}

Reply via email to