Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.graphics.predictor » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.pdfbox.pdmodel.graphics.predictor;
   18   
   19   import java.util.Random;
   20   
   21   /**
   22    * Implements different PNG predictor algorithms that is used in PDF files.
   23    *
   24    * @author xylifyx@yahoo.co.uk
   25    * @version $Revision: 1.4 $
   26    * @see <a href="http://www.w3.org/TR/PNG-Filters.html">PNG Filters</a>
   27    */
   28   public abstract class PredictorAlgorithm
   29   {
   30       private int width;
   31   
   32       private int height;
   33   
   34       private int bpp;
   35   
   36       /**
   37        * check that buffer sizes matches width,height,bpp. This implementation is
   38        * used by most of the filters, but not Uptimum.
   39        *
   40        * @param src The source buffer.
   41        * @param dest The destination buffer.
   42        */
   43       public void checkBufsiz(byte[] src, byte[] dest)
   44       {
   45           if (src.length != dest.length)
   46           {
   47               throw new IllegalArgumentException("src.length != dest.length");
   48           }
   49           if (src.length != getWidth() * getHeight() * getBpp())
   50           {
   51               throw new IllegalArgumentException(
   52                       "src.length != width * height * bpp");
   53           }
   54       }
   55   
   56       /**
   57        * encode line of pixel data in src from srcOffset and width*bpp bytes
   58        * forward, put the decoded bytes into dest.
   59        *
   60        * @param src
   61        *            raw image data
   62        * @param dest
   63        *            encoded data
   64        * @param srcDy
   65        *            byte offset between lines
   66        * @param srcOffset
   67        *            beginning of line data
   68        * @param destDy
   69        *            byte offset between lines
   70        * @param destOffset
   71        *            beginning of line data
   72        */
   73       public abstract void encodeLine(byte[] src, byte[] dest, int srcDy,
   74               int srcOffset, int destDy, int destOffset);
   75   
   76       /**
   77        * decode line of pixel data in src from src_offset and width*bpp bytes
   78        * forward, put the decoded bytes into dest.
   79        *
   80        * @param src
   81        *            encoded image data
   82        * @param dest
   83        *            raw data
   84        * @param srcDy
   85        *            byte offset between lines
   86        * @param srcOffset
   87        *            beginning of line data
   88        * @param destDy
   89        *            byte offset between lines
   90        * @param destOffset
   91        *            beginning of line data
   92        */
   93       public abstract void decodeLine(byte[] src, byte[] dest, int srcDy,
   94               int srcOffset, int destDy, int destOffset);
   95   
   96       /**
   97        * Simple command line program to test the algorithm.
   98        *
   99        * @param args The command line arguments.
  100        */
  101       public static void main(String[] args)
  102       {
  103           Random rnd = new Random();
  104           int width = 5;
  105           int height = 5;
  106           int bpp = 3;
  107           byte[] raw = new byte[width * height * bpp];
  108           rnd.nextBytes(raw);
  109           System.out.println("raw:   ");
  110           dump(raw);
  111           for (int i = 10; i < 15; i++)
  112           {
  113               byte[] decoded = new byte[width * height * bpp];
  114               byte[] encoded = new byte[width * height * bpp];
  115   
  116               PredictorAlgorithm filter = PredictorAlgorithm.getFilter(i);
  117               filter.setWidth(width);
  118               filter.setHeight(height);
  119               filter.setBpp(bpp);
  120               filter.encode(raw, encoded);
  121               filter.decode(encoded, decoded);
  122               System.out.println(filter.getClass().getName());
  123               dump(decoded);
  124           }
  125       }
  126   
  127       /**
  128        * Get the left pixel from the buffer.
  129        *
  130        * @param buf The buffer.
  131        * @param offset The offset into the buffer.
  132        * @param dy The dy value.
  133        * @param x The x value.
  134        *
  135        * @return The left pixel.
  136        */
  137       public int leftPixel(byte[] buf, int offset, int dy, int x)
  138       {
  139           return x >= getBpp() ? buf[offset + x - getBpp()] : 0;
  140       }
  141   
  142       /**
  143        * Get the above pixel from the buffer.
  144        *
  145        * @param buf The buffer.
  146        * @param offset The offset into the buffer.
  147        * @param dy The dy value.
  148        * @param x The x value.
  149        *
  150        * @return The above pixel.
  151        */
  152       public int abovePixel(byte[] buf, int offset, int dy, int x)
  153       {
  154           return offset >= dy ? buf[offset + x - dy] : 0;
  155       }
  156   
  157       /**
  158        * Get the above-left pixel from the buffer.
  159        *
  160        * @param buf The buffer.
  161        * @param offset The offset into the buffer.
  162        * @param dy The dy value.
  163        * @param x The x value.
  164        *
  165        * @return The above-left pixel.
  166        */
  167       public int aboveLeftPixel(byte[] buf, int offset, int dy, int x)
  168       {
  169           return offset >= dy && x >= getBpp() ? buf[offset + x - dy - getBpp()]
  170                   : 0;
  171       }
  172   
  173       /**
  174        * Simple helper to print out a buffer.
  175        *
  176        * @param raw The bytes to print out.
  177        */
  178       private static void dump(byte[] raw)
  179       {
  180           for (int i = 0; i < raw.length; i++)
  181           {
  182               System.out.print(raw[i] + " ");
  183           }
  184           System.out.println();
  185       }
  186   
  187       /**
  188        * @return Returns the bpp.
  189        */
  190       public int getBpp()
  191       {
  192           return bpp;
  193       }
  194   
  195       /**
  196        * @param newBpp
  197        *            The bpp to set.
  198        */
  199       public void setBpp(int newBpp)
  200       {
  201           bpp = newBpp;
  202       }
  203   
  204       /**
  205        * @return Returns the height.
  206        */
  207       public int getHeight()
  208       {
  209           return height;
  210       }
  211   
  212       /**
  213        * @param newHeight
  214        *            The height to set.
  215        */
  216       public void setHeight(int newHeight)
  217       {
  218           height = newHeight;
  219       }
  220   
  221       /**
  222        * @return Returns the width.
  223        */
  224       public int getWidth()
  225       {
  226           return width;
  227       }
  228   
  229       /**
  230        * @param newWidth
  231        *            The width to set.
  232        */
  233       public void setWidth(int newWidth)
  234       {
  235           this.width = newWidth;
  236       }
  237   
  238   
  239       /**
  240        * encode a byte array full of image data using the filter that this object
  241        * implements.
  242        *
  243        * @param src
  244        *            buffer
  245        * @param dest
  246        *            buffer
  247        */
  248       public void encode(byte[] src, byte[] dest)
  249       {
  250           checkBufsiz(dest, src);
  251           int dy = getWidth()*getBpp();
  252           for (int y = 0; y < height; y++)
  253           {
  254               int yoffset = y * dy;
  255               encodeLine(src, dest, dy, yoffset, dy, yoffset);
  256           }
  257       }
  258   
  259       /**
  260        * decode a byte array full of image data using the filter that this object
  261        * implements.
  262        *
  263        * @param src
  264        *            buffer
  265        * @param dest
  266        *            buffer
  267        */
  268       public void decode(byte[] src, byte[] dest)
  269       {
  270           checkBufsiz(src, dest);
  271           int dy = width * bpp;
  272           for (int y = 0; y < height; y++)
  273           {
  274               int yoffset = y * dy;
  275               decodeLine(src, dest, dy, yoffset, dy, yoffset);
  276           }
  277       }
  278   
  279       /**
  280        * @param predictor
  281        *            <ul>
  282        *            <li>1 No prediction (the default value)
  283        *            <li>2 TIFF Predictor 2
  284        *            <li>10 PNG prediction (on encoding, PNG None on all rows)
  285        *            <li>11 PNG prediction (on encoding, PNG Sub on all rows)
  286        *            <li>12 PNG prediction (on encoding, PNG Up on all rows)
  287        *            <li>13 PNG prediction (on encoding, PNG Average on all rows)
  288        *            <li>14 PNG prediction (on encoding, PNG Paeth on all rows)
  289        *            <li>15 PNG prediction (on encoding, PNG optimum)
  290        *            </ul>
  291        *
  292        * @return The predictor class based on the predictor code.
  293        */
  294       public static PredictorAlgorithm getFilter(int predictor)
  295       {
  296           PredictorAlgorithm filter;
  297           switch (predictor)
  298           {
  299               case 10:
  300                   filter = new None();
  301                   break;
  302               case 11:
  303                   filter = new Sub();
  304                   break;
  305               case 12:
  306                   filter = new Up();
  307                   break;
  308               case 13:
  309                   filter = new Average();
  310                   break;
  311               case 14:
  312                   filter = new Paeth();
  313                   break;
  314               case 15:
  315                   filter = new Optimum();
  316                   break;
  317               default:
  318                   filter = new None();
  319           }
  320           return filter;
  321       }
  322   }

Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.graphics.predictor » [javadoc | source]