import java.io.*; import java.nio.file.*; import java.util.*; import java.util.zip.*; import me.lemire.integercompression.differential.*; import me.lemire.integercompression.*; public class CompressBitmap { public static void main(String[] args) throws IOException { if(args.length == 0) { System.out.println("usage: please provide the file name of a bitmap binary file."); return; } System.out.println("loading file "+args[0]+" as a bitmap"); int[] data = fromBitsetFileToArray(args[0]); System.out.println("Compressing "+data.length+" integers"); int[] compressed = iic.compress(data); int[] recov = iic.uncompress(compressed); System.out.println("compressed from "+data.length*4/1024+"KB to "+compressed.length*4/1024+"KB"); System.out.println("ratio: "+Math.round(data.length*1.0/compressed.length)); if(!Arrays.equals(recov,data)) throw new RuntimeException("bug"); long bef,aft; bef = System.nanoTime(); recov = iic.uncompress(compressed); aft = System.nanoTime(); System.out.println("decoding speed:"+Math.round(data.length*1000.0/(aft-bef))+" millions of integers per second"); bef = System.nanoTime(); compressed = iic.compress(data); aft = System.nanoTime(); System.out.println("encoding speed:"+Math.round(data.length*1000.0/(aft-bef))+" millions of integers per second"); System.out.println("note: with a bit of effort, speed can be much higher."); System.out.println(); zipStats(args[0]); } static IntegratedIntCompressor iic = new IntegratedIntCompressor( new SkippableIntegratedComposition( new IntegratedBinaryPacking(), new IntegratedVariableByte())); public static int[] fromBitsetFileToArray(String filename) throws IOException { Path path = Paths.get(filename); byte[] data = Files.readAllBytes(path); // we determine cardinality int card = 0; for(int k = 0 ; k < data.length; ++k) { int bv = data[k] & 0xFF; card += Integer.bitCount(bv); } int[] answer = new int[card]; int pos = 0; for(int k = 0 ; k < data.length; ++k) { int bv = data[k] & 0xFF; for(int b = 0 ; b < 8; ++b) if ( ( (bv >> b) & 1 ) == 1) { answer[pos++] = b + k * 8; } } if(pos != card) throw new RuntimeException("bug"); return answer; } public static void zipStats(String filename) throws IOException { Path path = Paths.get(filename); byte[] input = Files.readAllBytes(path); System.out.println("I will try to compress the original bitmap using zip."); long bef = System.nanoTime(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(baos); zos.setLevel(9); ZipEntry entry = new ZipEntry(filename); entry.setSize(input.length); zos.putNextEntry(entry); zos.write(input); zos.closeEntry(); zos.close(); byte[] result = baos.toByteArray(); long aft = System.nanoTime(); System.out.println("zip encoding speed:"+input.length*1000.0/(aft-bef)+" million of bytes per second"); System.out.println("zip compression ratio at best level : "+input.length * 1.0 / result.length); } }