You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2018/02/09 17:06:24 UTC

[09/14] pdfbox-jbig2 git commit: PDFBOX-4098: reformat the source code, introduce an eclipse formatter definition

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java b/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java
index af4a26a..895741f 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/Bitmaps.java
@@ -32,538 +32,645 @@ import org.apache.pdfbox.jbig2.Bitmap;
 import org.apache.pdfbox.jbig2.JBIG2ReadParam;
 import org.apache.pdfbox.jbig2.util.CombinationOperator;
 
-public class Bitmaps {
+public class Bitmaps
+{
 
     /**
      * Returns the given bitmap as writable raster.
-     *  
+     * 
      * @param bitmap the given bitmap
      * @return the raster representation of the bitmap
      */
-     public static WritableRaster asRaster(final Bitmap bitmap) {
-         return asRaster(bitmap, FilterType.Gaussian);
-     }
+    public static WritableRaster asRaster(final Bitmap bitmap)
+    {
+        return asRaster(bitmap, FilterType.Gaussian);
+    }
 
     /**
      * Returns the given bitmap as writable raster.
-     *  
+     * 
      * @param bitmap the given bitmap
      * @param filterType type of filter which is used when creating the writable raster
      * @return the raster representation of the bitmap
      */
-    public static WritableRaster asRaster(final Bitmap bitmap, final FilterType filterType) {
+    public static WritableRaster asRaster(final Bitmap bitmap, final FilterType filterType)
+    {
         if (bitmap == null)
-          throw new IllegalArgumentException("bitmap must not be null");
-    
-        final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0, new Rectangle(0, 0, bitmap.getWidth(),
-            bitmap.getHeight()), new Dimension(bitmap.getWidth(), bitmap.getHeight()));
-    
+            throw new IllegalArgumentException("bitmap must not be null");
+
+        final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0,
+                new Rectangle(0, 0, bitmap.getWidth(), bitmap.getHeight()),
+                new Dimension(bitmap.getWidth(), bitmap.getHeight()));
+
         return asRaster(bitmap, param, filterType);
     }
 
     /**
      * Returns the given bitmap as writable raster.
-     *  
+     * 
      * @param bitmap the given bitmap
      * @param param ImageReadParam to be used when creating the writable raster
      * @param filterType type of filter which is used when creating the writable raster
      * @return the raster representation of the bitmap
      */
-  public static WritableRaster asRaster(Bitmap bitmap, final ImageReadParam param, final FilterType filterType) {
-    if (bitmap == null)
-      throw new IllegalArgumentException("bitmap must not be null");
-
-    if (param == null)
-      throw new IllegalArgumentException("param must not be null");
-
-    final Dimension sourceRenderSize = param.getSourceRenderSize();
-
-    double scaleX;
-    double scaleY;
-    if (sourceRenderSize != null) {
-      scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
-      scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
-    } else {
-      scaleX = scaleY = 1;
-    }
-
-    Rectangle sourceRegion = param.getSourceRegion();
-    if (sourceRegion != null && !bitmap.getBounds().equals(sourceRegion)) {
-      // make sure we don't request an area outside of the source bitmap
-      sourceRegion = bitmap.getBounds().intersection(sourceRegion);
+    public static WritableRaster asRaster(Bitmap bitmap, final ImageReadParam param,
+            final FilterType filterType)
+    {
+        if (bitmap == null)
+            throw new IllegalArgumentException("bitmap must not be null");
 
-      // get region of interest
-      bitmap = Bitmaps.extract(sourceRegion, bitmap);
-    }
+        if (param == null)
+            throw new IllegalArgumentException("param must not be null");
 
-    /*
-     * Subsampling is the advance of columns/rows for each pixel in the according direction. The
-     * resulting image's quality will be bad because we loose information if we step over
-     * columns/rows. For example, a thin line (1 pixel high) may disappear completely. To avoid this
-     * we use resize filters if scaling will be performed anyway. The resize filters use scale
-     * factors, one for horizontal and vertical direction. We care about the given subsampling steps
-     * by adjusting the scale factors. If scaling is not performed, subsampling is performed in its
-     * original manner.
-     */
+        final Dimension sourceRenderSize = param.getSourceRenderSize();
 
-    final boolean requiresScaling = scaleX != 1 || scaleY != 1;
-
-    final boolean requiresXSubsampling = param.getSourceXSubsampling() != 1;
-    final boolean requiresYSubsampling = param.getSourceYSubsampling() != 1;
-
-    if (requiresXSubsampling && requiresYSubsampling) {
-      // Apply vertical and horizontal subsampling
-      if (requiresScaling) {
-        scaleX /= (double) param.getSourceXSubsampling();
-        scaleY /= (double) param.getSourceYSubsampling();
-      } else {
-        bitmap = subsample(bitmap, param);
-      }
-    } else {
-      if (requiresXSubsampling) {
-        // Apply horizontal subsampling only
-        if (requiresScaling) {
-          scaleX /= (double) param.getSourceXSubsampling();
-        } else {
-          bitmap = Bitmaps.subsampleX(bitmap, param.getSourceXSubsampling(), param.getSubsamplingXOffset());
+        double scaleX;
+        double scaleY;
+        if (sourceRenderSize != null)
+        {
+            scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
+            scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
         }
-      }
-
-      if (requiresYSubsampling) {
-        // Apply vertical subsampling only
-        if (requiresScaling) {
-          scaleY /= (double) param.getSourceYSubsampling();
-        } else {
-          bitmap = Bitmaps.subsampleY(bitmap, param.getSourceYSubsampling(), param.getSubsamplingYOffset());
+        else
+        {
+            scaleX = scaleY = 1;
         }
-      }
-    }
 
-    return buildRaster(bitmap, filterType, scaleX, scaleY);
-  }
-
-  private static WritableRaster buildRaster(final Bitmap bitmap, final FilterType filterType, final double scaleX,
-      final double scaleY) {
-    final Rectangle dstBounds = new Rectangle(0, 0, //
-        (int) Math.round(bitmap.getWidth() * scaleX), //
-        (int) Math.round(bitmap.getHeight() * scaleY));
-
-    final WritableRaster dst = WritableRaster.createInterleavedRaster(DataBuffer.TYPE_BYTE, dstBounds.width,
-        dstBounds.height, 1, new Point());
-
-    if (scaleX != 1 || scaleY != 1) {
-      // scaling required
-      final Resizer resizer = new Resizer(scaleX, scaleY);
-      final Filter filter = Filter.byType(filterType);
-      resizer.resize(bitmap, bitmap.getBounds() /* sourceRegion */, dst, dstBounds, filter, filter);
-    } else {
-      // scaling not required, paste bitmap into raster pixel per pixel
-      int byteIndex = 0;
-      for (int y = 0; y < bitmap.getHeight(); y++) {
-        for (int x = 0; x < bitmap.getWidth(); byteIndex++) {
-          final int pixels = (~bitmap.getByte(byteIndex)) & 0xFF;
-          final int relevantPixels = bitmap.getWidth() - x > 8 ? 8 : bitmap.getWidth() - x;
-          final int endIdx = 7 - relevantPixels;
-          for (int bytePosition = 7; bytePosition > endIdx; bytePosition--, x++) {
-            dst.setSample(x, y, 0, (pixels >> bytePosition) & 0x1);
-          }
+        Rectangle sourceRegion = param.getSourceRegion();
+        if (sourceRegion != null && !bitmap.getBounds().equals(sourceRegion))
+        {
+            // make sure we don't request an area outside of the source bitmap
+            sourceRegion = bitmap.getBounds().intersection(sourceRegion);
+
+            // get region of interest
+            bitmap = Bitmaps.extract(sourceRegion, bitmap);
         }
-      }
-    }
 
-    return dst;
-  }
-
-  /**
-   * Returns the given bitmap as buffered image.
-   * 
-   * @param bitmap the given bitmap
-   * @return the image representation of the bitmap
-   */
-  public static BufferedImage asBufferedImage(Bitmap bitmap) {
-    return asBufferedImage(bitmap, FilterType.Gaussian);
-  }
-
-  /**
-   * Returns the given bitmap as buffered image.
-   * 
-   * @param bitmap the given bitmap
-   * @param filterType type of filter which is used when creating the buffered image
-   * @return the image representation of the bitmap
-   */
-  public static BufferedImage asBufferedImage(Bitmap bitmap, FilterType filterType) {
-    if (bitmap == null)
-      throw new IllegalArgumentException("bitmap must not be null");
-
-    final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0, new Rectangle(0, 0, bitmap.getWidth(),
-        bitmap.getHeight()), new Dimension(bitmap.getWidth(), bitmap.getHeight()));
-
-    return asBufferedImage(bitmap, param, filterType);
-  }
-
-  /**
-   * Returns the given bitmap as buffered image.
-   * 
-   * @param bitmap the given bitmap
-   * @param param ImageReadParam to be used when creating the buffered image
-   * @param filterType type of filter which is used when creating the buffered image
-   * @return the image representation of the bitmap
-   */
-  public static BufferedImage asBufferedImage(Bitmap bitmap, ImageReadParam param, FilterType filterType) {
-    if (bitmap == null)
-      throw new IllegalArgumentException("bitmap must not be null");
-
-    if (param == null)
-      throw new IllegalArgumentException("param must not be null");
-
-    final WritableRaster raster = asRaster(bitmap, param, filterType);
-
-    final Dimension sourceRenderSize = param.getSourceRenderSize();
-
-    final double scaleX;
-    final double scaleY;
-    if (sourceRenderSize != null) {
-      scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
-      scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
-    } else {
-      scaleX = scaleY = 1d;
-    }
+        /*
+         * Subsampling is the advance of columns/rows for each pixel in the according direction. The resulting image's
+         * quality will be bad because we loose information if we step over columns/rows. For example, a thin line (1
+         * pixel high) may disappear completely. To avoid this we use resize filters if scaling will be performed
+         * anyway. The resize filters use scale factors, one for horizontal and vertical direction. We care about the
+         * given subsampling steps by adjusting the scale factors. If scaling is not performed, subsampling is performed
+         * in its original manner.
+         */
+
+        final boolean requiresScaling = scaleX != 1 || scaleY != 1;
+
+        final boolean requiresXSubsampling = param.getSourceXSubsampling() != 1;
+        final boolean requiresYSubsampling = param.getSourceYSubsampling() != 1;
+
+        if (requiresXSubsampling && requiresYSubsampling)
+        {
+            // Apply vertical and horizontal subsampling
+            if (requiresScaling)
+            {
+                scaleX /= (double) param.getSourceXSubsampling();
+                scaleY /= (double) param.getSourceYSubsampling();
+            }
+            else
+            {
+                bitmap = subsample(bitmap, param);
+            }
+        }
+        else
+        {
+            if (requiresXSubsampling)
+            {
+                // Apply horizontal subsampling only
+                if (requiresScaling)
+                {
+                    scaleX /= (double) param.getSourceXSubsampling();
+                }
+                else
+                {
+                    bitmap = Bitmaps.subsampleX(bitmap, param.getSourceXSubsampling(),
+                            param.getSubsamplingXOffset());
+                }
+            }
+
+            if (requiresYSubsampling)
+            {
+                // Apply vertical subsampling only
+                if (requiresScaling)
+                {
+                    scaleY /= (double) param.getSourceYSubsampling();
+                }
+                else
+                {
+                    bitmap = Bitmaps.subsampleY(bitmap, param.getSourceYSubsampling(),
+                            param.getSubsamplingYOffset());
+                }
+            }
+        }
 
-    ColorModel cm = null;
-    final boolean isScaled = scaleX != 1 || scaleY != 1;
-    if (isScaled) {
-      final int size = 256;
-      final int divisor = size - 1;
-
-      final byte[] gray = new byte[size];
-      for (int i = size - 1, s = 0; i >= 0; i--, s++) {
-        gray[i] = (byte) (255 - s * 255 / divisor);
-      }
-      cm = new IndexColorModel(8, size, gray, gray, gray);
-    } else {
-
-      cm = new IndexColorModel(8, 2, //
-          new byte[]{
-              0x00, (byte) 0xff
-          }, new byte[]{
-              0x00, (byte) 0xff
-          }, new byte[]{
-              0x00, (byte) 0xff
-          });
+        return buildRaster(bitmap, filterType, scaleX, scaleY);
     }
 
-    return new BufferedImage(cm, raster, false, null);
-  }
-
-  /**
-   * Returns the specified rectangle area of the bitmap.
-   * 
-   * @param roi - A {@link Rectangle} that specifies the requested image section.
-   * @param src the given bitmap
-   * @return A {@code Bitmap} that represents the requested image section.
-   */
-  public static Bitmap extract(final Rectangle roi, final Bitmap src) {
-    final Bitmap dst = new Bitmap(roi.width, roi.height);
-
-    final int upShift = roi.x & 0x07;
-    final int downShift = 8 - upShift;
-    int dstLineStartIdx = 0;
-
-    final int padding = (8 - dst.getWidth() & 0x07);
-    int srcLineStartIdx = src.getByteIndex(roi.x, roi.y);
-    int srcLineEndIdx = src.getByteIndex(roi.x + roi.width - 1, roi.y);
-    final boolean usePadding = dst.getRowStride() == srcLineEndIdx + 1 - srcLineStartIdx;
-
-    for (int y = roi.y; y < roi.getMaxY(); y++) {
-      int srcIdx = srcLineStartIdx;
-      int dstIdx = dstLineStartIdx;
-
-      if (srcLineStartIdx == srcLineEndIdx) {
-        final byte pixels = (byte) (src.getByte(srcIdx) << upShift);
-        dst.setByte(dstIdx, unpad(padding, pixels));
-      } else if (upShift == 0) {
-        for (int x = srcLineStartIdx; x <= srcLineEndIdx; x++) {
-          byte value = src.getByte(srcIdx++);
-
-          if (x == srcLineEndIdx && usePadding) {
-            value = unpad(padding, value);
-          }
-
-          dst.setByte(dstIdx++, value);
+    private static WritableRaster buildRaster(final Bitmap bitmap, final FilterType filterType,
+            final double scaleX, final double scaleY)
+    {
+        final Rectangle dstBounds = new Rectangle(0, 0, //
+                (int) Math.round(bitmap.getWidth() * scaleX), //
+                (int) Math.round(bitmap.getHeight() * scaleY));
+
+        final WritableRaster dst = WritableRaster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                dstBounds.width, dstBounds.height, 1, new Point());
+
+        if (scaleX != 1 || scaleY != 1)
+        {
+            // scaling required
+            final Resizer resizer = new Resizer(scaleX, scaleY);
+            final Filter filter = Filter.byType(filterType);
+            resizer.resize(bitmap, bitmap.getBounds() /* sourceRegion */, dst, dstBounds, filter,
+                    filter);
+        }
+        else
+        {
+            // scaling not required, paste bitmap into raster pixel per pixel
+            int byteIndex = 0;
+            for (int y = 0; y < bitmap.getHeight(); y++)
+            {
+                for (int x = 0; x < bitmap.getWidth(); byteIndex++)
+                {
+                    final int pixels = (~bitmap.getByte(byteIndex)) & 0xFF;
+                    final int relevantPixels = bitmap.getWidth() - x > 8 ? 8
+                            : bitmap.getWidth() - x;
+                    final int endIdx = 7 - relevantPixels;
+                    for (int bytePosition = 7; bytePosition > endIdx; bytePosition--, x++)
+                    {
+                        dst.setSample(x, y, 0, (pixels >> bytePosition) & 0x1);
+                    }
+                }
+            }
         }
-      } else {
-        copyLine(src, dst, upShift, downShift, padding, srcLineStartIdx, srcLineEndIdx, usePadding, srcIdx, dstIdx);
-      }
 
-      srcLineStartIdx += src.getRowStride();
-      srcLineEndIdx += src.getRowStride();
-      dstLineStartIdx += dst.getRowStride();
+        return dst;
     }
 
-    return dst;
-  }
-
-  private static void copyLine(Bitmap src, Bitmap dst, int sourceUpShift, int sourceDownShift, int padding,
-      int firstSourceByteOfLine, int lastSourceByteOfLine, boolean usePadding, int sourceOffset, int targetOffset) {
-    for (int x = firstSourceByteOfLine; x < lastSourceByteOfLine; x++) {
-
-      if (sourceOffset + 1 < src.getByteArray().length) {
-        final boolean isLastByte = x + 1 == lastSourceByteOfLine;
-        byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift | (src.getByte(sourceOffset) & 0xff) >>> sourceDownShift);
-
-        if (isLastByte && !usePadding) {
-          value = unpad(padding, value);
-        }
+    /**
+     * Returns the given bitmap as buffered image.
+     * 
+     * @param bitmap the given bitmap
+     * @return the image representation of the bitmap
+     */
+    public static BufferedImage asBufferedImage(Bitmap bitmap)
+    {
+        return asBufferedImage(bitmap, FilterType.Gaussian);
+    }
 
-        dst.setByte(targetOffset++, value);
+    /**
+     * Returns the given bitmap as buffered image.
+     * 
+     * @param bitmap the given bitmap
+     * @param filterType type of filter which is used when creating the buffered image
+     * @return the image representation of the bitmap
+     */
+    public static BufferedImage asBufferedImage(Bitmap bitmap, FilterType filterType)
+    {
+        if (bitmap == null)
+            throw new IllegalArgumentException("bitmap must not be null");
 
-        if (isLastByte && usePadding) {
-          value = unpad(padding, (byte) ((src.getByte(sourceOffset) & 0xff) << sourceUpShift));
-          dst.setByte(targetOffset, value);
-        }
+        final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0,
+                new Rectangle(0, 0, bitmap.getWidth(), bitmap.getHeight()),
+                new Dimension(bitmap.getWidth(), bitmap.getHeight()));
 
-      } else {
-        final byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift & 0xff);
-        dst.setByte(targetOffset++, value);
-      }
-    }
-  }
-
-  /**
-   * Removes unnecessary bits from a byte.
-   * 
-   * @param padding - The amount of unnecessary bits.
-   * @param value - The byte that should be cleaned up.
-   * @return A cleaned byte.
-   */
-  private static byte unpad(int padding, byte value) {
-    return (byte) (value >> padding << padding);
-  }
-
-  public static Bitmap subsample(Bitmap src, ImageReadParam param) {
-    if (src == null)
-      throw new IllegalArgumentException("src must not be null");
-
-    if (param == null)
-      throw new IllegalArgumentException("param must not be null");
-
-    final int xSubsampling = param.getSourceXSubsampling();
-    final int ySubsampling = param.getSourceYSubsampling();
-    final int xSubsamplingOffset = param.getSubsamplingXOffset();
-    final int ySubsamplingOffset = param.getSubsamplingYOffset();
-
-    final int dstWidth = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
-    final int dstHeight = (src.getHeight() - ySubsamplingOffset) / ySubsampling;
-
-    final Bitmap dst = new Bitmap(dstWidth, dstHeight);
-
-    for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst.getHeight(); yDst++, ySrc += ySubsampling) {
-      for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst.getWidth(); xDst++, xSrc += xSubsampling) {
-        final byte pixel = src.getPixel(xSrc, ySrc);
-        if (pixel != 0)
-          dst.setPixel(xDst, yDst, pixel);
-      }
+        return asBufferedImage(bitmap, param, filterType);
     }
 
-    return dst;
-  }
+    /**
+     * Returns the given bitmap as buffered image.
+     * 
+     * @param bitmap the given bitmap
+     * @param param ImageReadParam to be used when creating the buffered image
+     * @param filterType type of filter which is used when creating the buffered image
+     * @return the image representation of the bitmap
+     */
+    public static BufferedImage asBufferedImage(Bitmap bitmap, ImageReadParam param,
+            FilterType filterType)
+    {
+        if (bitmap == null)
+            throw new IllegalArgumentException("bitmap must not be null");
 
-  public static Bitmap subsampleX(Bitmap src, final int xSubsampling, final int xSubsamplingOffset) {
-    if (src == null)
-      throw new IllegalArgumentException("src must not be null");
+        if (param == null)
+            throw new IllegalArgumentException("param must not be null");
 
-    final int dstHeight = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
-    final Bitmap dst = new Bitmap(src.getWidth(), dstHeight);
+        final WritableRaster raster = asRaster(bitmap, param, filterType);
 
-    for (int yDst = 0; yDst < dst.getHeight(); yDst++) {
-      for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst.getWidth(); xDst++, xSrc += xSubsampling) {
-        final byte pixel = src.getPixel(xSrc, yDst);
-        if (pixel != 0)
-          dst.setPixel(xDst, yDst, pixel);
-      }
-    }
+        final Dimension sourceRenderSize = param.getSourceRenderSize();
 
-    return dst;
-  }
+        final double scaleX;
+        final double scaleY;
+        if (sourceRenderSize != null)
+        {
+            scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
+            scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
+        }
+        else
+        {
+            scaleX = scaleY = 1d;
+        }
 
-  public static Bitmap subsampleY(Bitmap src, final int ySubsampling, final int ySubsamplingOffset) {
-    if (src == null)
-      throw new IllegalArgumentException("src must not be null");
+        ColorModel cm = null;
+        final boolean isScaled = scaleX != 1 || scaleY != 1;
+        if (isScaled)
+        {
+            final int size = 256;
+            final int divisor = size - 1;
+
+            final byte[] gray = new byte[size];
+            for (int i = size - 1, s = 0; i >= 0; i--, s++)
+            {
+                gray[i] = (byte) (255 - s * 255 / divisor);
+            }
+            cm = new IndexColorModel(8, size, gray, gray, gray);
+        }
+        else
+        {
 
-    final int dstWidth = (src.getWidth() - ySubsamplingOffset) / ySubsampling;
-    final Bitmap dst = new Bitmap(dstWidth, src.getHeight());
+            cm = new IndexColorModel(8, 2, //
+                    new byte[] { 0x00, (byte) 0xff }, new byte[] { 0x00, (byte) 0xff },
+                    new byte[] { 0x00, (byte) 0xff });
+        }
 
-    for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst.getHeight(); yDst++, ySrc += ySubsampling) {
-      for (int xDst = 0; xDst < dst.getWidth(); xDst++) {
-        final byte pixel = src.getPixel(xDst, ySrc);
-        if (pixel != 0)
-          dst.setPixel(xDst, yDst, pixel);
-      }
+        return new BufferedImage(cm, raster, false, null);
     }
 
-    return dst;
-  }
-
-  /**
-   * The method combines two given bytes with an logical operator.
-   * <p>
-   * The JBIG2 Standard specifies 5 possible combinations of bytes.<br>
-   * <p>
-   * <b>Hint:</b> Please take a look at ISO/IEC 14492:2001 (E) for detailed definition and
-   * description of the operators.
-   * 
-   * @param value1 - The value that should be combined with value2.
-   * @param value2 - The value that should be combined with value1.
-   * @param op - The specified combination operator.
-   * 
-   * @return The combination result.
-   */
-  public static byte combineBytes(byte value1, byte value2, CombinationOperator op) {
-
-    switch (op){
-      case OR :
-        return (byte) (value2 | value1);
-      case AND :
-        return (byte) (value2 & value1);
-      case XOR :
-        return (byte) (value2 ^ value1);
-      case XNOR :
-        return (byte) ~(value1 ^ value2);
-      case REPLACE :
-      default :
-        // Old value is replaced by new value.
-        return value2;
-    }
-  }
-
-  /**
-   * This method combines a given bitmap with the current instance.
-   * <p>
-   * Parts of the bitmap to blit that are outside of the target bitmap will be ignored.
-   * 
-   * @param src - The bitmap that should be combined with the one of the current instance.
-   * @param dst - The destination bitmap.
-   * @param x - The x coordinate where the upper left corner of the bitmap to blit should be
-   *          positioned.
-   * @param y - The y coordinate where the upper left corner of the bitmap to blit should be
-   *          positioned.
-   * @param combinationOperator - The combination operator for combining two pixels.
-   */
-  public static void blit(Bitmap src, Bitmap dst, int x, int y, CombinationOperator combinationOperator) {
-
-    int startLine = 0;
-    int srcStartIdx = 0;
-    int srcEndIdx = (src.getRowStride() - 1);
-
-    // Ignore those parts of the source bitmap which would be placed outside the target bitmap.
-    if (x < 0) {
-      srcStartIdx = -x;
-      x = 0;
-    } else if (x + src.getWidth() > dst.getWidth()) {
-      srcEndIdx -= (src.getWidth() + x - dst.getWidth());
-    }
+    /**
+     * Returns the specified rectangle area of the bitmap.
+     * 
+     * @param roi - A {@link Rectangle} that specifies the requested image section.
+     * @param src the given bitmap
+     * @return A {@code Bitmap} that represents the requested image section.
+     */
+    public static Bitmap extract(final Rectangle roi, final Bitmap src)
+    {
+        final Bitmap dst = new Bitmap(roi.width, roi.height);
+
+        final int upShift = roi.x & 0x07;
+        final int downShift = 8 - upShift;
+        int dstLineStartIdx = 0;
+
+        final int padding = (8 - dst.getWidth() & 0x07);
+        int srcLineStartIdx = src.getByteIndex(roi.x, roi.y);
+        int srcLineEndIdx = src.getByteIndex(roi.x + roi.width - 1, roi.y);
+        final boolean usePadding = dst.getRowStride() == srcLineEndIdx + 1 - srcLineStartIdx;
+
+        for (int y = roi.y; y < roi.getMaxY(); y++)
+        {
+            int srcIdx = srcLineStartIdx;
+            int dstIdx = dstLineStartIdx;
+
+            if (srcLineStartIdx == srcLineEndIdx)
+            {
+                final byte pixels = (byte) (src.getByte(srcIdx) << upShift);
+                dst.setByte(dstIdx, unpad(padding, pixels));
+            }
+            else if (upShift == 0)
+            {
+                for (int x = srcLineStartIdx; x <= srcLineEndIdx; x++)
+                {
+                    byte value = src.getByte(srcIdx++);
+
+                    if (x == srcLineEndIdx && usePadding)
+                    {
+                        value = unpad(padding, value);
+                    }
+
+                    dst.setByte(dstIdx++, value);
+                }
+            }
+            else
+            {
+                copyLine(src, dst, upShift, downShift, padding, srcLineStartIdx, srcLineEndIdx,
+                        usePadding, srcIdx, dstIdx);
+            }
+
+            srcLineStartIdx += src.getRowStride();
+            srcLineEndIdx += src.getRowStride();
+            dstLineStartIdx += dst.getRowStride();
+        }
 
-    if (y < 0) {
-      startLine = -y;
-      y = 0;
-      srcStartIdx += src.getRowStride();
-      srcEndIdx += src.getRowStride();
-    } else if (y + src.getHeight() > dst.getHeight()) {
-      startLine = src.getHeight() + y - dst.getHeight();
+        return dst;
     }
 
-    final int shiftVal1 = x & 0x07;
-    final int shiftVal2 = 8 - shiftVal1;
-
-    final int padding = src.getWidth() & 0x07;
-    final int toShift = shiftVal2 - padding;
-
-    final boolean useShift = (shiftVal2 & 0x07) != 0;
-    final boolean specialCase = src.getWidth() <= ((srcEndIdx - srcStartIdx) << 3) + shiftVal2;
+    private static void copyLine(Bitmap src, Bitmap dst, int sourceUpShift, int sourceDownShift,
+            int padding, int firstSourceByteOfLine, int lastSourceByteOfLine, boolean usePadding,
+            int sourceOffset, int targetOffset)
+    {
+        for (int x = firstSourceByteOfLine; x < lastSourceByteOfLine; x++)
+        {
+
+            if (sourceOffset + 1 < src.getByteArray().length)
+            {
+                final boolean isLastByte = x + 1 == lastSourceByteOfLine;
+                byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift
+                        | (src.getByte(sourceOffset) & 0xff) >>> sourceDownShift);
+
+                if (isLastByte && !usePadding)
+                {
+                    value = unpad(padding, value);
+                }
+
+                dst.setByte(targetOffset++, value);
+
+                if (isLastByte && usePadding)
+                {
+                    value = unpad(padding,
+                            (byte) ((src.getByte(sourceOffset) & 0xff) << sourceUpShift));
+                    dst.setByte(targetOffset, value);
+                }
+
+            }
+            else
+            {
+                final byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift & 0xff);
+                dst.setByte(targetOffset++, value);
+            }
+        }
+    }
 
-    final int dstStartIdx = dst.getByteIndex(x, y);
+    /**
+     * Removes unnecessary bits from a byte.
+     * 
+     * @param padding - The amount of unnecessary bits.
+     * @param value - The byte that should be cleaned up.
+     * @return A cleaned byte.
+     */
+    private static byte unpad(int padding, byte value)
+    {
+        return (byte) (value >> padding << padding);
+    }
 
-    final int lastLine = Math.min(src.getHeight(), startLine + dst.getHeight());
+    public static Bitmap subsample(Bitmap src, ImageReadParam param)
+    {
+        if (src == null)
+            throw new IllegalArgumentException("src must not be null");
+
+        if (param == null)
+            throw new IllegalArgumentException("param must not be null");
+
+        final int xSubsampling = param.getSourceXSubsampling();
+        final int ySubsampling = param.getSourceYSubsampling();
+        final int xSubsamplingOffset = param.getSubsamplingXOffset();
+        final int ySubsamplingOffset = param.getSubsamplingYOffset();
+
+        final int dstWidth = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
+        final int dstHeight = (src.getHeight() - ySubsamplingOffset) / ySubsampling;
+
+        final Bitmap dst = new Bitmap(dstWidth, dstHeight);
+
+        for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst
+                .getHeight(); yDst++, ySrc += ySubsampling)
+        {
+            for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst
+                    .getWidth(); xDst++, xSrc += xSubsampling)
+            {
+                final byte pixel = src.getPixel(xSrc, ySrc);
+                if (pixel != 0)
+                    dst.setPixel(xDst, yDst, pixel);
+            }
+        }
 
-    if (!useShift) {
-      blitUnshifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, combinationOperator);
-    } else if (specialCase) {
-      blitSpecialShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, toShift, shiftVal1,
-          shiftVal2, combinationOperator);
-    } else {
-      blitShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, toShift, shiftVal1, shiftVal2,
-          combinationOperator, padding);
+        return dst;
     }
-  }
 
-  private static void blitUnshifted(Bitmap src, Bitmap dst, int startLine, int lastLine, int dstStartIdx,
-      int srcStartIdx, int srcEndIdx, CombinationOperator op) {
-
-    for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst.getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride()) {
-      int dstIdx = dstStartIdx;
+    public static Bitmap subsampleX(Bitmap src, final int xSubsampling,
+            final int xSubsamplingOffset)
+    {
+        if (src == null)
+            throw new IllegalArgumentException("src must not be null");
+
+        final int dstHeight = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
+        final Bitmap dst = new Bitmap(src.getWidth(), dstHeight);
+
+        for (int yDst = 0; yDst < dst.getHeight(); yDst++)
+        {
+            for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst
+                    .getWidth(); xDst++, xSrc += xSubsampling)
+            {
+                final byte pixel = src.getPixel(xSrc, yDst);
+                if (pixel != 0)
+                    dst.setPixel(xDst, yDst, pixel);
+            }
+        }
 
-      // Go through the bytes in a line of the Symbol
-      for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++) {
-        byte oldByte = dst.getByte(dstIdx);
-        byte newByte = src.getByte(srcIdx);
-        dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
-      }
+        return dst;
     }
-  }
 
-  private static void blitSpecialShifted(Bitmap src, Bitmap dst, int startLine, int lastLine, int dstStartIdx,
-      int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1, int shiftVal2, CombinationOperator op) {
+    public static Bitmap subsampleY(Bitmap src, final int ySubsampling,
+            final int ySubsamplingOffset)
+    {
+        if (src == null)
+            throw new IllegalArgumentException("src must not be null");
+
+        final int dstWidth = (src.getWidth() - ySubsamplingOffset) / ySubsampling;
+        final Bitmap dst = new Bitmap(dstWidth, src.getHeight());
+
+        for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst
+                .getHeight(); yDst++, ySrc += ySubsampling)
+        {
+            for (int xDst = 0; xDst < dst.getWidth(); xDst++)
+            {
+                final byte pixel = src.getPixel(xDst, ySrc);
+                if (pixel != 0)
+                    dst.setPixel(xDst, yDst, pixel);
+            }
+        }
 
-    for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst.getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride()) {
-      short register = 0;
-      int dstIdx = dstStartIdx;
+        return dst;
+    }
 
-      // Go through the bytes in a line of the Symbol
-      for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++) {
-        byte oldByte = dst.getByte(dstIdx);
-        register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
-        byte newByte = (byte) (register >> 8);
+    /**
+     * The method combines two given bytes with an logical operator.
+     * <p>
+     * The JBIG2 Standard specifies 5 possible combinations of bytes.<br>
+     * <p>
+     * <b>Hint:</b> Please take a look at ISO/IEC 14492:2001 (E) for detailed definition and description of the
+     * operators.
+     * 
+     * @param value1 - The value that should be combined with value2.
+     * @param value2 - The value that should be combined with value1.
+     * @param op - The specified combination operator.
+     * 
+     * @return The combination result.
+     */
+    public static byte combineBytes(byte value1, byte value2, CombinationOperator op)
+    {
+
+        switch (op)
+        {
+        case OR:
+            return (byte) (value2 | value1);
+        case AND:
+            return (byte) (value2 & value1);
+        case XOR:
+            return (byte) (value2 ^ value1);
+        case XNOR:
+            return (byte) ~(value1 ^ value2);
+        case REPLACE:
+        default:
+            // Old value is replaced by new value.
+            return value2;
+        }
+    }
 
-        if (srcIdx == srcEndIdx) {
-          newByte = unpad(toShift, newByte);
+    /**
+     * This method combines a given bitmap with the current instance.
+     * <p>
+     * Parts of the bitmap to blit that are outside of the target bitmap will be ignored.
+     * 
+     * @param src - The bitmap that should be combined with the one of the current instance.
+     * @param dst - The destination bitmap.
+     * @param x - The x coordinate where the upper left corner of the bitmap to blit should be positioned.
+     * @param y - The y coordinate where the upper left corner of the bitmap to blit should be positioned.
+     * @param combinationOperator - The combination operator for combining two pixels.
+     */
+    public static void blit(Bitmap src, Bitmap dst, int x, int y,
+            CombinationOperator combinationOperator)
+    {
+
+        int startLine = 0;
+        int srcStartIdx = 0;
+        int srcEndIdx = (src.getRowStride() - 1);
+
+        // Ignore those parts of the source bitmap which would be placed outside the target bitmap.
+        if (x < 0)
+        {
+            srcStartIdx = -x;
+            x = 0;
+        }
+        else if (x + src.getWidth() > dst.getWidth())
+        {
+            srcEndIdx -= (src.getWidth() + x - dst.getWidth());
         }
 
-        dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
-        register <<= shiftVal1;
-      }
-    }
-  }
+        if (y < 0)
+        {
+            startLine = -y;
+            y = 0;
+            srcStartIdx += src.getRowStride();
+            srcEndIdx += src.getRowStride();
+        }
+        else if (y + src.getHeight() > dst.getHeight())
+        {
+            startLine = src.getHeight() + y - dst.getHeight();
+        }
 
-  private static void blitShifted(Bitmap src, Bitmap dst, int startLine, int lastLine, int dstStartIdx,
-      int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1, int shiftVal2, CombinationOperator op, int padding) {
+        final int shiftVal1 = x & 0x07;
+        final int shiftVal2 = 8 - shiftVal1;
 
-    for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst.getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride()) {
-      short register = 0;
-      int dstIdx = dstStartIdx;
+        final int padding = src.getWidth() & 0x07;
+        final int toShift = shiftVal2 - padding;
 
-      // Go through the bytes in a line of the symbol
-      for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++) {
-        byte oldByte = dst.getByte(dstIdx);
-        register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
+        final boolean useShift = (shiftVal2 & 0x07) != 0;
+        final boolean specialCase = src.getWidth() <= ((srcEndIdx - srcStartIdx) << 3) + shiftVal2;
 
-        byte newByte = (byte) (register >> 8);
-        dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
+        final int dstStartIdx = dst.getByteIndex(x, y);
 
-        register <<= shiftVal1;
+        final int lastLine = Math.min(src.getHeight(), startLine + dst.getHeight());
 
-        if (srcIdx == srcEndIdx) {
-          newByte = (byte) (register >> (8 - shiftVal2));
+        if (!useShift)
+        {
+            blitUnshifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx,
+                    combinationOperator);
+        }
+        else if (specialCase)
+        {
+            blitSpecialShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx,
+                    toShift, shiftVal1, shiftVal2, combinationOperator);
+        }
+        else
+        {
+            blitShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, toShift,
+                    shiftVal1, shiftVal2, combinationOperator, padding);
+        }
+    }
 
-          if (padding != 0) {
-            newByte = unpad(8 + toShift, newByte);
-          }
+    private static void blitUnshifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
+            int dstStartIdx, int srcStartIdx, int srcEndIdx, CombinationOperator op)
+    {
+
+        for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
+                .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
+        {
+            int dstIdx = dstStartIdx;
+
+            // Go through the bytes in a line of the Symbol
+            for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
+            {
+                byte oldByte = dst.getByte(dstIdx);
+                byte newByte = src.getByte(srcIdx);
+                dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
+            }
+        }
+    }
 
-          oldByte = dst.getByte(dstIdx);
-          dst.setByte(dstIdx, Bitmaps.combineBytes(oldByte, newByte, op));
+    private static void blitSpecialShifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
+            int dstStartIdx, int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1,
+            int shiftVal2, CombinationOperator op)
+    {
+
+        for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
+                .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
+        {
+            short register = 0;
+            int dstIdx = dstStartIdx;
+
+            // Go through the bytes in a line of the Symbol
+            for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
+            {
+                byte oldByte = dst.getByte(dstIdx);
+                register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
+                byte newByte = (byte) (register >> 8);
+
+                if (srcIdx == srcEndIdx)
+                {
+                    newByte = unpad(toShift, newByte);
+                }
+
+                dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
+                register <<= shiftVal1;
+            }
         }
-      }
     }
-  }
 
+    private static void blitShifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
+            int dstStartIdx, int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1,
+            int shiftVal2, CombinationOperator op, int padding)
+    {
+
+        for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
+                .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
+        {
+            short register = 0;
+            int dstIdx = dstStartIdx;
+
+            // Go through the bytes in a line of the symbol
+            for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
+            {
+                byte oldByte = dst.getByte(dstIdx);
+                register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
+
+                byte newByte = (byte) (register >> 8);
+                dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
+
+                register <<= shiftVal1;
+
+                if (srcIdx == srcEndIdx)
+                {
+                    newByte = (byte) (register >> (8 - shiftVal2));
+
+                    if (padding != 0)
+                    {
+                        newByte = unpad(8 + toShift, newByte);
+                    }
+
+                    oldByte = dst.getByte(dstIdx);
+                    dst.setByte(dstIdx, Bitmaps.combineBytes(oldByte, newByte, op));
+                }
+            }
+        }
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java b/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java
index 2b81957..bdcdad6 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/Filter.java
@@ -17,441 +17,512 @@
 
 package org.apache.pdfbox.jbig2.image;
 
-
-abstract class Filter {
-
-  /**
-   * Find a filter name by its type.
-   * 
-   * @param type the filter type
-   * @return filter name
-   */
-  public static String nameByType(final FilterType type) {
-    if (type == null)
-      throw new IllegalArgumentException("type must not be null");
-    return type.name();
-  }
-
-  /**
-   * Find a filter type by its name.
-   * 
-   * @param name the filter name
-   * @return filter type
-   */
-  public static FilterType typeByName(final String name) {
-    if (name == null)
-      throw new IllegalArgumentException("name must not be null");
-    return FilterType.valueOf(name);
-  }
-
-  /**
-   * Find a filter by its type.
-   * 
-   * @param type the filter type
-   * @return the Filter
-   */
-  public static Filter byType(final FilterType type) {
-    switch (type){
-      case Bessel :
-        return new Bessel();
-      case Blackman :
-        return new Blackman();
-      case Box :
-        return new Box();
-      case Catrom :
-        return new Catrom();
-      case Cubic :
-        return new Cubic();
-      case Gaussian :
-        return new Gaussian();
-      case Hamming :
-        return new Hamming();
-      case Hanning :
-        return new Hanning();
-      case Hermite :
-        return new Hermite();
-      case Lanczos :
-        return new Lanczos();
-      case Mitchell :
-        return new Mitchell();
-      case Point :
-        return new Point();
-      case Quadratic :
-        return new Quadratic();
-      case Sinc :
-        return new Sinc();
-      case Triangle :
-        return new Triangle();
-    }
-    throw new IllegalArgumentException("No filter for given type.");
-  }
-
-  public static final class Bessel extends Filter {
-    public Bessel() {
-      super(false, 3.2383, 1.0);
-    }
-
-    private double J1(final double x) {
-      double p, q;
-
-      int i;
-
-      final double Pone[] = {
-          0.581199354001606143928050809e+21, -0.6672106568924916298020941484e+20, 0.2316433580634002297931815435e+19,
-          -0.3588817569910106050743641413e+17, 0.2908795263834775409737601689e+15, -0.1322983480332126453125473247e+13,
-          0.3413234182301700539091292655e+10, -0.4695753530642995859767162166e+7, 0.270112271089232341485679099e+4
-      }, Qone[] = {
-          0.11623987080032122878585294e+22, 0.1185770712190320999837113348e+20, 0.6092061398917521746105196863e+17,
-          0.2081661221307607351240184229e+15, 0.5243710262167649715406728642e+12, 0.1013863514358673989967045588e+10,
-          0.1501793594998585505921097578e+7, 0.1606931573481487801970916749e+4, 0.1e+1
-      };
-
-      p = Pone[8];
-      q = Qone[8];
-      for (i = 7; i >= 0; i--) {
-        p = p * x * x + Pone[i];
-        q = q * x * x + Qone[i];
-      }
-      return p / q;
-    }
-
-    private double P1(final double x) {
-      double p, q;
-
-      int i;
-
-      final double Pone[] = {
-          0.352246649133679798341724373e+5, 0.62758845247161281269005675e+5, 0.313539631109159574238669888e+5,
-          0.49854832060594338434500455e+4, 0.2111529182853962382105718e+3, 0.12571716929145341558495e+1
-      }, Qone[] = {
-          0.352246649133679798068390431e+5, 0.626943469593560511888833731e+5, 0.312404063819041039923015703e+5,
-          0.4930396490181088979386097e+4, 0.2030775189134759322293574e+3, 0.1e+1
-      };
-
-      p = Pone[5];
-      q = Qone[5];
-      for (i = 4; i >= 0; i--) {
-        p = p * (8.0 / x) * (8.0 / x) + Pone[i];
-        q = q * (8.0 / x) * (8.0 / x) + Qone[i];
-      }
-      return p / q;
-    }
-
-    private double Q1(final double x) {
-      double p, q;
-
-      int i;
-
-      final double Pone[] = {
-          0.3511751914303552822533318e+3, 0.7210391804904475039280863e+3, 0.4259873011654442389886993e+3,
-          0.831898957673850827325226e+2, 0.45681716295512267064405e+1, 0.3532840052740123642735e-1
-      }, Qone[] = {
-          0.74917374171809127714519505e+4, 0.154141773392650970499848051e+5, 0.91522317015169922705904727e+4,
-          0.18111867005523513506724158e+4, 0.1038187585462133728776636e+3, 0.1e+1
-      };
-
-      p = Pone[5];
-      q = Qone[5];
-      for (i = 4; i >= 0; i--) {
-        p = p * (8.0 / x) * (8.0 / x) + Pone[i];
-        q = q * (8.0 / x) * (8.0 / x) + Qone[i];
-      }
-      return p / q;
-    }
-
-    private double BesselOrderOne(double x) {
-      double p, q;
-
-      if (x == 0.0)
-        return 0.0;
-      p = x;
-      if (x < 0.0)
-        x = -x;
-      if (x < 8.0)
-        return p * J1(x);
-      q = Math.sqrt(2.0 / (Math.PI * x))
-          * (P1(x) * (1.0 / Math.sqrt(2.0) * (Math.sin(x) - Math.cos(x))) - 8.0 / x * Q1(x)
-              * (-1.0 / Math.sqrt(2.0) * (Math.sin(x) + Math.cos(x))));
-      if (p < 0.0)
-        q = -q;
-      return q;
-    }
-
-    @Override
-    public double f(final double x) {
-      if (x == 0.0)
-        return Math.PI / 4.0;
-      return BesselOrderOne(Math.PI * x) / (2.0 * x);
-    }
-  }
-
-  public static final class Blackman extends Filter {
-    @Override
-    public double f(final double x) {
-      return 0.42 + 0.50 * Math.cos(Math.PI * x) + 0.08 * Math.cos(2.0 * Math.PI * x);
-    }
-  }
-
-  public static class Box extends Filter {
-    public Box() {
-      super(true, .5, 1.0);
-    }
-
-    public Box(final double supp) {
-      super(true, supp, 1.0);
-    }
-
-    @Override
-    public double f(final double x) {
-      if (x >= -0.5 && x < 0.5)
-        return 1.0;
-      return 0.0;
-    }
-  }
-
-  public static final class Point extends Box {
-    public Point() {
-      super(0);
-    }
-
-    @Override
-    public double fWindowed(double x) {
-      // don't apply windowing as we have a radius of zero.
-      return super.f(x);
-    }
-  }
-
-  public static final class Catrom extends Filter {
-    public Catrom() {
-      super(true, 2.0, 1.0);
-    }
-
-    @Override
-    public double f(double x) {
-      if (x < 0)
-        x = -x;
-      if (x < 1.0)
-        return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
-      if (x < 2.0)
-        return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
-      return 0.0;
-    }
-  }
-
-  public static final class Cubic extends Filter {
-    public Cubic() {
-      super(false, 2.0, 1.0);
-    }
-
-    @Override
-    public double f(double x) {
-      if (x < 0)
-        x = -x;
-      if (x < 1.0)
-        return 0.5 * x * x * x - x * x + 2.0 / 3.0;
-      if (x < 2.0) {
-        x = 2.0 - x;
-        return 1.0 / 6.0 * x * x * x;
-      }
-      return 0.0;
-    }
-  }
-
-  public static final class Gaussian extends Filter {
-    public Gaussian() {
-      super(false, 1.25, 1.0);
-    }
-
-    @Override
-    public double f(final double x) {
-      return Math.exp(-2.0 * x * x) * Math.sqrt(2.0 / Math.PI);
-    }
-  }
-
-  public static final class Hamming extends Filter {
-    @Override
-    public double f(final double x) {
-      return 0.54 + 0.46 * Math.cos(Math.PI * x);
-    }
-  }
-
-  public static final class Hanning extends Filter {
-    @Override
-    public double f(final double x) {
-      return 0.5 + 0.5 * Math.cos(Math.PI * x);
-    }
-  }
-
-  public static final class Hermite extends Filter {
-    @Override
-    public double f(double x) {
-      if (x < 0) {
-        x = -x;
-      }
-
-      if (x < 1.0) {
-        return (2.0 * x - 3.0) * x * x + 1.0;
-      }
-      return 0.0;
-    }
-  }
-
-  public static final class Lanczos extends Filter {
-    public Lanczos() {
-      super(true, 3.0, 1.0);
-    }
-
-    @Override
-    public double f(double x) {
-      if (x < 0)
-        x = -x;
-      if (x < 3.0)
-        return (float) (sinc(x) * sinc(x / 3.0));
-      return 0.0;
-    }
-
-    private double sinc(double value) {
-      if (value != 0.0f) {
-        value = value * Math.PI;
-        return Math.sin(value) / value;
-      } else {
-        return 1.0;
-      }
-    }
-
-  }
-
-  public static final class Mitchell extends Filter {
-    public Mitchell() {
-      super(false, 2.0, 1.0);
-    }
-
-    @Override
-    public double f(double x) {
-      double b, c;
-
-      b = 1.0 / 3.0;
-      c = 1.0 / 3.0;
-      if (x < 0)
-        x = -x;
-      if (x < 1.0) {
-        x = (12.0 - 9.0 * b - 6.0 * c) * (x * x * x) + (-18.0 + 12.0 * b + 6.0 * c) * x * x + (6.0 - 2.0 * b);
-        return x / 6.0;
-      }
-      if (x < 2.0) {
-        x = (-1.0 * b - 6.0 * c) * (x * x * x) + (6.0 * b + 30.0 * c) * x * x + (-12.0 * b - 48.0 * c) * x
-            + (8.0 * b + 24.0 * c);
-        return x / 6.0;
-      }
-      return 0.0;
-    }
-  }
-
-  public static final class Quadratic extends Filter {
-    public Quadratic() {
-      super(false, 1.5, 1.0);
-    }
-
-    @Override
-    public double f(double x) {
-      if (x < 0)
-        x = -x;
-      if (x < 0.5)
-        return 0.75 - x * x;
-      if (x < 1.5) {
-        x -= 1.5;
-        return 0.5 * x * x;
-      }
-      return 0.0;
-    }
-  }
-
-  public static final class Sinc extends Filter {
-    public Sinc() {
-      super(true, 4.0, 1.0);
-    }
-
-    @Override
-    public double f(double x) {
-      x *= Math.PI;
-      if (x != 0.0)
-        return Math.sin(x) / x;
-      return 1.0;
-    }
-  }
-
-  public static final class Triangle extends Filter {
-    @Override
-    public double f(double x) {
-      if (x < 0.0)
-        x = -x;
-      if (x < 1.0)
-        return 1.0 - x;
-      return 0.0;
+abstract class Filter
+{
+
+    /**
+     * Find a filter name by its type.
+     * 
+     * @param type the filter type
+     * @return filter name
+     */
+    public static String nameByType(final FilterType type)
+    {
+        if (type == null)
+            throw new IllegalArgumentException("type must not be null");
+        return type.name();
+    }
+
+    /**
+     * Find a filter type by its name.
+     * 
+     * @param name the filter name
+     * @return filter type
+     */
+    public static FilterType typeByName(final String name)
+    {
+        if (name == null)
+            throw new IllegalArgumentException("name must not be null");
+        return FilterType.valueOf(name);
+    }
+
+    /**
+     * Find a filter by its type.
+     * 
+     * @param type the filter type
+     * @return the Filter
+     */
+    public static Filter byType(final FilterType type)
+    {
+        switch (type)
+        {
+        case Bessel:
+            return new Bessel();
+        case Blackman:
+            return new Blackman();
+        case Box:
+            return new Box();
+        case Catrom:
+            return new Catrom();
+        case Cubic:
+            return new Cubic();
+        case Gaussian:
+            return new Gaussian();
+        case Hamming:
+            return new Hamming();
+        case Hanning:
+            return new Hanning();
+        case Hermite:
+            return new Hermite();
+        case Lanczos:
+            return new Lanczos();
+        case Mitchell:
+            return new Mitchell();
+        case Point:
+            return new Point();
+        case Quadratic:
+            return new Quadratic();
+        case Sinc:
+            return new Sinc();
+        case Triangle:
+            return new Triangle();
+        }
+        throw new IllegalArgumentException("No filter for given type.");
+    }
+
+    public static final class Bessel extends Filter
+    {
+        public Bessel()
+        {
+            super(false, 3.2383, 1.0);
+        }
+
+        private double J1(final double x)
+        {
+            double p, q;
+
+            int i;
+
+            final double Pone[] = { 0.581199354001606143928050809e+21,
+                    -0.6672106568924916298020941484e+20, 0.2316433580634002297931815435e+19,
+                    -0.3588817569910106050743641413e+17, 0.2908795263834775409737601689e+15,
+                    -0.1322983480332126453125473247e+13, 0.3413234182301700539091292655e+10,
+                    -0.4695753530642995859767162166e+7, 0.270112271089232341485679099e+4 },
+                    Qone[] = { 0.11623987080032122878585294e+22, 0.1185770712190320999837113348e+20,
+                            0.6092061398917521746105196863e+17, 0.2081661221307607351240184229e+15,
+                            0.5243710262167649715406728642e+12, 0.1013863514358673989967045588e+10,
+                            0.1501793594998585505921097578e+7, 0.1606931573481487801970916749e+4,
+                            0.1e+1 };
+
+            p = Pone[8];
+            q = Qone[8];
+            for (i = 7; i >= 0; i--)
+            {
+                p = p * x * x + Pone[i];
+                q = q * x * x + Qone[i];
+            }
+            return p / q;
+        }
+
+        private double P1(final double x)
+        {
+            double p, q;
+
+            int i;
+
+            final double Pone[] = { 0.352246649133679798341724373e+5,
+                    0.62758845247161281269005675e+5, 0.313539631109159574238669888e+5,
+                    0.49854832060594338434500455e+4, 0.2111529182853962382105718e+3,
+                    0.12571716929145341558495e+1 },
+                    Qone[] = { 0.352246649133679798068390431e+5, 0.626943469593560511888833731e+5,
+                            0.312404063819041039923015703e+5, 0.4930396490181088979386097e+4,
+                            0.2030775189134759322293574e+3, 0.1e+1 };
+
+            p = Pone[5];
+            q = Qone[5];
+            for (i = 4; i >= 0; i--)
+            {
+                p = p * (8.0 / x) * (8.0 / x) + Pone[i];
+                q = q * (8.0 / x) * (8.0 / x) + Qone[i];
+            }
+            return p / q;
+        }
+
+        private double Q1(final double x)
+        {
+            double p, q;
+
+            int i;
+
+            final double Pone[] = { 0.3511751914303552822533318e+3, 0.7210391804904475039280863e+3,
+                    0.4259873011654442389886993e+3, 0.831898957673850827325226e+2,
+                    0.45681716295512267064405e+1, 0.3532840052740123642735e-1 },
+                    Qone[] = { 0.74917374171809127714519505e+4, 0.154141773392650970499848051e+5,
+                            0.91522317015169922705904727e+4, 0.18111867005523513506724158e+4,
+                            0.1038187585462133728776636e+3, 0.1e+1 };
+
+            p = Pone[5];
+            q = Qone[5];
+            for (i = 4; i >= 0; i--)
+            {
+                p = p * (8.0 / x) * (8.0 / x) + Pone[i];
+                q = q * (8.0 / x) * (8.0 / x) + Qone[i];
+            }
+            return p / q;
+        }
+
+        private double BesselOrderOne(double x)
+        {
+            double p, q;
+
+            if (x == 0.0)
+                return 0.0;
+            p = x;
+            if (x < 0.0)
+                x = -x;
+            if (x < 8.0)
+                return p * J1(x);
+            q = Math.sqrt(2.0 / (Math.PI * x))
+                    * (P1(x) * (1.0 / Math.sqrt(2.0) * (Math.sin(x) - Math.cos(x))) - 8.0 / x
+                            * Q1(x) * (-1.0 / Math.sqrt(2.0) * (Math.sin(x) + Math.cos(x))));
+            if (p < 0.0)
+                q = -q;
+            return q;
+        }
+
+        @Override
+        public double f(final double x)
+        {
+            if (x == 0.0)
+                return Math.PI / 4.0;
+            return BesselOrderOne(Math.PI * x) / (2.0 * x);
+        }
+    }
+
+    public static final class Blackman extends Filter
+    {
+        @Override
+        public double f(final double x)
+        {
+            return 0.42 + 0.50 * Math.cos(Math.PI * x) + 0.08 * Math.cos(2.0 * Math.PI * x);
+        }
+    }
+
+    public static class Box extends Filter
+    {
+        public Box()
+        {
+            super(true, .5, 1.0);
+        }
+
+        public Box(final double supp)
+        {
+            super(true, supp, 1.0);
+        }
+
+        @Override
+        public double f(final double x)
+        {
+            if (x >= -0.5 && x < 0.5)
+                return 1.0;
+            return 0.0;
+        }
+    }
+
+    public static final class Point extends Box
+    {
+        public Point()
+        {
+            super(0);
+        }
+
+        @Override
+        public double fWindowed(double x)
+        {
+            // don't apply windowing as we have a radius of zero.
+            return super.f(x);
+        }
+    }
+
+    public static final class Catrom extends Filter
+    {
+        public Catrom()
+        {
+            super(true, 2.0, 1.0);
+        }
+
+        @Override
+        public double f(double x)
+        {
+            if (x < 0)
+                x = -x;
+            if (x < 1.0)
+                return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0));
+            if (x < 2.0)
+                return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x)));
+            return 0.0;
+        }
+    }
+
+    public static final class Cubic extends Filter
+    {
+        public Cubic()
+        {
+            super(false, 2.0, 1.0);
+        }
+
+        @Override
+        public double f(double x)
+        {
+            if (x < 0)
+                x = -x;
+            if (x < 1.0)
+                return 0.5 * x * x * x - x * x + 2.0 / 3.0;
+            if (x < 2.0)
+            {
+                x = 2.0 - x;
+                return 1.0 / 6.0 * x * x * x;
+            }
+            return 0.0;
+        }
+    }
+
+    public static final class Gaussian extends Filter
+    {
+        public Gaussian()
+        {
+            super(false, 1.25, 1.0);
+        }
+
+        @Override
+        public double f(final double x)
+        {
+            return Math.exp(-2.0 * x * x) * Math.sqrt(2.0 / Math.PI);
+        }
+    }
+
+    public static final class Hamming extends Filter
+    {
+        @Override
+        public double f(final double x)
+        {
+            return 0.54 + 0.46 * Math.cos(Math.PI * x);
+        }
+    }
+
+    public static final class Hanning extends Filter
+    {
+        @Override
+        public double f(final double x)
+        {
+            return 0.5 + 0.5 * Math.cos(Math.PI * x);
+        }
+    }
+
+    public static final class Hermite extends Filter
+    {
+        @Override
+        public double f(double x)
+        {
+            if (x < 0)
+            {
+                x = -x;
+            }
+
+            if (x < 1.0)
+            {
+                return (2.0 * x - 3.0) * x * x + 1.0;
+            }
+            return 0.0;
+        }
+    }
+
+    public static final class Lanczos extends Filter
+    {
+        public Lanczos()
+        {
+            super(true, 3.0, 1.0);
+        }
+
+        @Override
+        public double f(double x)
+        {
+            if (x < 0)
+                x = -x;
+            if (x < 3.0)
+                return (float) (sinc(x) * sinc(x / 3.0));
+            return 0.0;
+        }
+
+        private double sinc(double value)
+        {
+            if (value != 0.0f)
+            {
+                value = value * Math.PI;
+                return Math.sin(value) / value;
+            }
+            else
+            {
+                return 1.0;
+            }
+        }
+
+    }
+
+    public static final class Mitchell extends Filter
+    {
+        public Mitchell()
+        {
+            super(false, 2.0, 1.0);
+        }
+
+        @Override
+        public double f(double x)
+        {
+            double b, c;
+
+            b = 1.0 / 3.0;
+            c = 1.0 / 3.0;
+            if (x < 0)
+                x = -x;
+            if (x < 1.0)
+            {
+                x = (12.0 - 9.0 * b - 6.0 * c) * (x * x * x) + (-18.0 + 12.0 * b + 6.0 * c) * x * x
+                        + (6.0 - 2.0 * b);
+                return x / 6.0;
+            }
+            if (x < 2.0)
+            {
+                x = (-1.0 * b - 6.0 * c) * (x * x * x) + (6.0 * b + 30.0 * c) * x * x
+                        + (-12.0 * b - 48.0 * c) * x + (8.0 * b + 24.0 * c);
+                return x / 6.0;
+            }
+            return 0.0;
+        }
+    }
+
+    public static final class Quadratic extends Filter
+    {
+        public Quadratic()
+        {
+            super(false, 1.5, 1.0);
+        }
+
+        @Override
+        public double f(double x)
+        {
+            if (x < 0)
+                x = -x;
+            if (x < 0.5)
+                return 0.75 - x * x;
+            if (x < 1.5)
+            {
+                x -= 1.5;
+                return 0.5 * x * x;
+            }
+            return 0.0;
+        }
+    }
+
+    public static final class Sinc extends Filter
+    {
+        public Sinc()
+        {
+            super(true, 4.0, 1.0);
+        }
+
+        @Override
+        public double f(double x)
+        {
+            x *= Math.PI;
+            if (x != 0.0)
+                return Math.sin(x) / x;
+            return 1.0;
+        }
+    }
+
+    public static final class Triangle extends Filter
+    {
+        @Override
+        public double f(double x)
+        {
+            if (x < 0.0)
+                x = -x;
+            if (x < 1.0)
+                return 1.0 - x;
+            return 0.0;
+        }
+    }
+
+    /**
+     * is this filter cardinal? ie, does func(x) = (x==0) for integer x?
+     */
+    final boolean cardinal;
+
+    /** radius of nonzero portion */
+    double support;
+
+    /** blur factor (1=normal) */
+    double blur;
+
+    protected Filter()
+    {
+        this(true, 1.0, 1.0);
+    }
+
+    protected Filter(final boolean cardinal, final double support, final double blur)
+    {
+        this.cardinal = cardinal;
+        this.support = support;
+        this.blur = blur;
+    }
+
+    public double fWindowed(double x)
+    {
+        return x < -support || x > support ? 0 : f(x);
+    }
+
+    public abstract double f(double x);
+
+    /**
+     * Return the filter name.
+     * 
+     * @return the filter's name
+     */
+    public String getName()
+    {
+        return getClass().getSimpleName();
+    }
+
+    /**
+     * @return the support
+     */
+    public double getSupport()
+    {
+        return support;
+    }
+
+    /**
+     * @param support the support to set
+     */
+    public void setSupport(final double support)
+    {
+        this.support = support;
+    }
+
+    /**
+     * @return the blur
+     */
+    public double getBlur()
+    {
+        return blur;
+    }
+
+    /**
+     * @param blur the blur to set
+     */
+    public void setBlur(final double blur)
+    {
+        this.blur = blur;
     }
-  }
-
-  /**
-   * is this filter cardinal? ie, does func(x) = (x==0) for integer x?
-   */
-  final boolean cardinal;
-
-  /** radius of nonzero portion */
-  double support;
-
-  /** blur factor (1=normal) */
-  double blur;
-
-  protected Filter() {
-    this(true, 1.0, 1.0);
-  }
-
-  protected Filter(final boolean cardinal, final double support, final double blur) {
-    this.cardinal = cardinal;
-    this.support = support;
-    this.blur = blur;
-  }
-
-  public double fWindowed(double x) {
-    return x < -support || x > support ? 0 : f(x);
-  }
-
-  public abstract double f(double x);
-
-  /**
-   * Return the filter name.
-   * 
-   * @return the filter's name
-   */
-  public String getName() {
-    return getClass().getSimpleName();
-  }
-
-  /**
-   * @return the support
-   */
-  public double getSupport() {
-    return support;
-  }
-
-  /**
-   * @param support the support to set
-   */
-  public void setSupport(final double support) {
-    this.support = support;
-  }
-
-  /**
-   * @return the blur
-   */
-  public double getBlur() {
-    return blur;
-  }
-
-  /**
-   * @param blur the blur to set
-   */
-  public void setBlur(final double blur) {
-    this.blur = blur;
-  }
 }

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java b/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java
index 1420726..6d3e0e2 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/FilterType.java
@@ -17,34 +17,22 @@
 
 package org.apache.pdfbox.jbig2.image;
 
-
 /**
  * A FilterType enum for defining certain downscale filters to apply.
  */
-public enum FilterType {
-  Bessel,
-  Blackman,
-  Box,
-  Catrom,
-  Cubic,
-  Gaussian,
-  Hamming,
-  Hanning,
-  Hermite,
-  Lanczos,
-  Mitchell,
-  Point,
-  Quadratic,
-  Sinc,
-  Triangle;
+public enum FilterType
+{
+    Bessel, Blackman, Box, Catrom, Cubic, Gaussian, Hamming, Hanning, Hermite, Lanczos, Mitchell, Point, Quadratic, Sinc, Triangle;
 
-  private static FilterType defaultFilter = Triangle;
+    private static FilterType defaultFilter = Triangle;
 
-  public static void setDefaultFilterType(FilterType defaultFilter) {
-    FilterType.defaultFilter = defaultFilter;
-  }
+    public static void setDefaultFilterType(FilterType defaultFilter)
+    {
+        FilterType.defaultFilter = defaultFilter;
+    }
 
-  public static FilterType getDefaultFilterType() {
-    return defaultFilter;
-  }
-}
\ No newline at end of file
+    public static FilterType getDefaultFilterType()
+    {
+        return defaultFilter;
+    }
+}

http://git-wip-us.apache.org/repos/asf/pdfbox-jbig2/blob/30839c32/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java b/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java
index bc32755..e801296 100644
--- a/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java
+++ b/src/main/java/org/apache/pdfbox/jbig2/image/ParameterizedFilter.java
@@ -19,51 +19,56 @@ package org.apache.pdfbox.jbig2.image;
 
 import org.apache.pdfbox.jbig2.util.Utils;
 
-class ParameterizedFilter {
-  public ParameterizedFilter(final Filter f, final double scale) {
-    filter = f;
-    /*
-     * find scale of filter in a space (source space) when minifying, ascale=1/scale, but when
-     * magnifying, ascale=1
-     */
-    this.scale = f.blur * Math.max(1., 1. / scale);
+class ParameterizedFilter
+{
+    public ParameterizedFilter(final Filter f, final double scale)
+    {
+        filter = f;
+        /*
+         * find scale of filter in a space (source space) when minifying, ascale=1/scale, but when magnifying, ascale=1
+         */
+        this.scale = f.blur * Math.max(1., 1. / scale);
 
-    /*
-     * find support radius of scaled filter if ax.supp and ay.supp are both <=.5 then we've got
-     * point sampling. Point sampling is essentially a special filter whose width is fixed at one
-     * source pixel.
-     */
-    support = Math.max(.5, this.scale * f.support);
-    width = (int) Math.ceil(2. * support);
-  }
+        /*
+         * find support radius of scaled filter if ax.supp and ay.supp are both <=.5 then we've got point sampling.
+         * Point sampling is essentially a special filter whose width is fixed at one source pixel.
+         */
+        support = Math.max(.5, this.scale * f.support);
+        width = (int) Math.ceil(2. * support);
+    }
 
-  public ParameterizedFilter(final Filter f, final double scale, final double support, final int width) {
-    filter = f;
-    this.scale = scale;
-    this.support = support;
-    this.width = width;
-  }
+    public ParameterizedFilter(final Filter f, final double scale, final double support,
+            final int width)
+    {
+        filter = f;
+        this.scale = scale;
+        this.support = support;
+        this.width = width;
+    }
 
-  final Filter filter;
+    final Filter filter;
 
-  /* filter scale (spacing between centers in a space) */
-  final double scale;
+    /* filter scale (spacing between centers in a space) */
+    final double scale;
 
-  /* scaled filter support radius */
-  final double support;
+    /* scaled filter support radius */
+    final double support;
 
-  /* filter width: max number of nonzero samples */
-  final int width;
+    /* filter width: max number of nonzero samples */
+    final int width;
 
-  public double eval(double center, int i) {
-    return filter.fWindowed((i + .5 - center) / scale);
-  }
+    public double eval(double center, int i)
+    {
+        return filter.fWindowed((i + .5 - center) / scale);
+    }
 
-  public int minIndex(double center) {
-    return Utils.floor(center - support);
-  }
+    public int minIndex(double center)
+    {
+        return Utils.floor(center - support);
+    }
 
-  public int maxIndex(double center) {
-    return Utils.ceil(center + support);
-  }
-}
\ No newline at end of file
+    public int maxIndex(double center)
+    {
+        return Utils.ceil(center + support);
+    }
+}