Mega Code Archive

 
Categories / Java / 2D Graphics GUI
 

ImageComparator compares a byte[] for equality by creating 2 hashes for the bytearray and comparing thoose hashes

/**  *   * JFreeReport : a free Java reporting library  *   *  * Project Info:  http://reporting.pentaho.org/  *  * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.  *  * This library is free software; you can redistribute it and/or modify it under the terms  * of the GNU Lesser General Public License as published by the Free Software Foundation;  * either version 2.1 of the License, or (at your option) any later version.  *  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  * See the GNU Lesser General Public License for more details.  *  * You should have received a copy of the GNU Lesser General Public License along with this  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,  * Boston, MA 02111-1307, USA.  *  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.  * in the United States and other countries.]  *  * ------------  * ImageComparator.java  * ------------  * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.  */ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; /**  * The ImageComparator tries to compare a byte[] for equality by creating 2 hashes for the  * bytearray and comparing thoose hashes. If no digest algorithms are available, then the  * complete byte[] is used for comparison.  * <p>  * Using the digest method trades computing time for space.  *  * @author Thomas Morgner  */ public class ImageComparator {   /**    * A ImageCompareData that uses the complete image data for comparison.    */   private static final class CompleteImageCompareData   {     /**      * The image content.      */     private final byte[] image;     /**      * Create a new CompleteImageCompareData instance.      *      * @param image the image data used for comparison.      */     private CompleteImageCompareData (final byte[] image)     {       this.image = image;     }     /**      * Checks whether the given Object equals this object.      *      * @param o the to be compared object      * @return true, if both objects are equal      */     public boolean equals (final Object o)     {       if (this == o)       {         return true;       }       if (!(o instanceof CompleteImageCompareData))       {         return false;       }       final CompleteImageCompareData data = (CompleteImageCompareData) o;       if (!Arrays.equals(image, data.image))       {         return false;       }       return true;     }     /**      * returns a hashcode for this class.      *      * @return always 0.      */     public int hashCode ()     {       return image.length;     }   }   /**    * An ImageComparator which uses precomputed Message-Digests to compare the image.    */   private static final class DigestImageCompareData   {     /**      * An MD5 digest.      */     private byte[] digestMD5Data;     /**      * An SHA digest.      */     private byte[] digestSHAData;     /**      * Creates a new DigestImageCompareData instance.      *      * @param digestMD5Data the MD5 digest data      * @param digestSHAData the SHA1 digest data      */     private DigestImageCompareData (final byte[] digestMD5Data,                                     final byte[] digestSHAData)     {       if (digestMD5Data == null || digestSHAData == null)       {         throw new NullPointerException();       }       this.digestMD5Data = digestMD5Data;       this.digestSHAData = digestSHAData;     }     /**      * Checks whether the given Object equals this object.      *      * @param o the to be compared object      * @return true, if both objects are equal      */     public boolean equals (final Object o)     {       if (this == o)       {         return true;       }       if (!(o instanceof DigestImageCompareData))       {         return false;       }       final DigestImageCompareData data = (DigestImageCompareData) o;       if (!Arrays.equals(digestMD5Data, data.digestMD5Data))       {         return false;       }       if (!Arrays.equals(digestSHAData, data.digestSHAData))       {         return false;       }       return true;     }     /**      * returns a hashcode for this class.      *      * @return always 0.      */     public int hashCode ()     {       return 0;     }   }   /**    * An MD5 message digest.    */   private MessageDigest digestMD5;   /**    * An SHA message digest.    */   private MessageDigest digestSHA;   /**    * Creates a new ImageComparator. The comparator checks whether the MD5 and the SHA    * message digest implementations are available. If they are not available, an    * alternative comparison method is used, which is more memory consuming.    */   public ImageComparator ()   {     try     {       digestMD5 = MessageDigest.getInstance("MD5");     }     catch (NoSuchAlgorithmException nse)     {       System.out.println("No MD5 algorithm available");     }     try     {       digestSHA = MessageDigest.getInstance("SHA");     }     catch (NoSuchAlgorithmException nse)     {       System.out.println("No SHA algorithm available");     }   }   /**    * Creates 2 comparable objects. These objects can be compared for equality.    *    * @param image the image data which should be prepared for comparison    * @param fast  whether to prefer the memory intensive faster compare method to the    *              digest based comparation. This may result in outofmemory errors on huge    *              reports or images.    * @return the prepared image data.    */   public Object createCompareData (final byte[] image, final boolean fast)   {     if (fast == false && (digestMD5 != null && digestSHA != null))     {       final byte[] dataMD5 = digestMD5.digest(image);       final byte[] dataSHA = digestSHA.digest(image);       if (dataSHA != null && dataMD5 != null)       {         return new DigestImageCompareData(dataMD5, dataSHA);       }     }     return new CompleteImageCompareData(image);   } }