// Path: src/com/ciphertechsolutions/io/ewf/DataChunk.java
// public class DataChunk {
//     /**
//      * The raw data.
//      */
//     public final byte[] data;
//     /**
//      * The size of the data, in bytes.
//      */
//     public final int size;
//     /**
//      * The size of the uncompressed data, may be equal to size if {@link #compressed} is false.
//      */
//     public final int originalSize;
//     /**
//      * Whether this data is compressed.
//      */
//     public final boolean compressed;
// 
//     /**
//      * Makes a {@link DataChunk} with the given data.
//      * @param originalSize The uncompressed size of the data.
//      * @param data The (possibly compressed) data.
//      * @param compressed Whether or not the data given is compressed.
//      */
//     public DataChunk(int originalSize, byte[] data, boolean compressed) {
//         this.data = data;
//         this.originalSize = originalSize;
//         this.size = this.data.length;
//         this.compressed = compressed;
//     }
// }
// 
// Path: src/com/ciphertechsolutions/io/processing/triage/ByteUtils.java
// public class ByteUtils {
// 
// 	/**
// 	 * Converts a long to a little endian byte array.
// 	 * @param l The long to convert
// 	 * @return A little endian array.
// 	 */
//     public static byte[] longToBytes(long l) {
//         byte[] result = new byte[8];
//         for (int i = 0; i <= 7; i++) {
//             result[i] = (byte)(l & 0xFF);
//             l >>= 8;
//         }
//         return result;
//     }
// 
//     /**
//      * Converts an int to a little endian byte array.
//      * @param _int The int to convert.
//      * @return A little endian array.
//      */
//     public static byte[] intToBytes(int _int) {
//         byte[] result = new byte[4];
//         for (int i = 0; i <= 3; i++) {
//             result[i] = (byte)(_int & 0xFF);
//             _int >>= 8;
//         }
//         return result;
//     }
// 
//     public static Map<Integer, String> printableSpansWithIndexes(byte[] bytes, int minLength, boolean filterRandom, int randomThreshold) {
// 
//         Map<Integer, String> spanPairs = new HashMap<>();
//         int[] table = new int[bytes.length];
//         int tableSize = 0;
//         int strStart, strSize;
//         byte[] byteSpan;
//         String span;
// 
// 
//         for (int i = 0; i < bytes.length; i++)
//         {
//             if (!isPrintable(bytes[i]))
//             {
//                 table[tableSize++] = i;
//             }
//         }
// 
//         for (int j = 1; j < tableSize; j++)
//         {
//             if (table[j] == 0)
//             {
//                 continue;
//             }
// 
//             strStart = table[j - 1] + 1;
//             strSize = table[j] - strStart;
// 
//             if (strSize < minLength)
//             {
//                 continue;
//             }
// 
// 
//             byteSpan = Arrays.copyOfRange(bytes, strStart, strStart + strSize);
//             span = new String(byteSpan, StandardCharsets.US_ASCII);
//             spanPairs.put(strStart, span);
//         }
// 
//         if (filterRandom)
//         {
//             //TODO: Bother with this?
//             return spanPairs;
//         }
//         else
//         {
//             return spanPairs;
//         }
//     }
// 
//     private static boolean isPrintable(byte b)
//     {
//         return (b >= 0x20 && b < 0x7F) || b == 0x0a || b == 0x0d || b == 0x09;
//     }
// }


import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import javax.xml.bind.DatatypeConverter;
import com.ciphertechsolutions.io.ewf.DataChunk;
import com.ciphertechsolutions.io.processing.triage.ByteUtils;
package com.ciphertechsolutions.io.processing;




class CompressionTask implements Callable<DataChunk> {

    private final byte[] input;
    private final int compressionLevel;

    CompressionTask(byte[] toCompress, int compressionLevel) {
        input = toCompress;
        this.compressionLevel = compressionLevel;
    }

    @Override
    public DataChunk call() throws Exception {
        Deflater deflater = new Deflater(compressionLevel);
        deflater.setInput(input);
        deflater.finish();
        byte[] output = new byte[input.length + 4];
        int compressedSize = deflater.deflate(output);
        //Unlikely, but possible.
        if (compressedSize >= input.length) {
            System.arraycopy(input, 0, output, 0, input.length);
// Path: src/com/ciphertechsolutions/io/ewf/DataChunk.java
// public class DataChunk {
//     /**
//      * The raw data.
//      */
//     public final byte[] data;
//     /**
//      * The size of the data, in bytes.
//      */
//     public final int size;
//     /**
//      * The size of the uncompressed data, may be equal to size if {@link #compressed} is false.
//      */
//     public final int originalSize;
//     /**
//      * Whether this data is compressed.
//      */
//     public final boolean compressed;
// 
//     /**
//      * Makes a {@link DataChunk} with the given data.
//      * @param originalSize The uncompressed size of the data.
//      * @param data The (possibly compressed) data.
//      * @param compressed Whether or not the data given is compressed.
//      */
//     public DataChunk(int originalSize, byte[] data, boolean compressed) {
//         this.data = data;
//         this.originalSize = originalSize;
//         this.size = this.data.length;
//         this.compressed = compressed;
//     }
// }
// 
// Path: src/com/ciphertechsolutions/io/processing/triage/ByteUtils.java
// public class ByteUtils {
// 
// 	/**
// 	 * Converts a long to a little endian byte array.
// 	 * @param l The long to convert
// 	 * @return A little endian array.
// 	 */
//     public static byte[] longToBytes(long l) {
//         byte[] result = new byte[8];
//         for (int i = 0; i <= 7; i++) {
//             result[i] = (byte)(l & 0xFF);
//             l >>= 8;
//         }
//         return result;
//     }
// 
//     /**
//      * Converts an int to a little endian byte array.
//      * @param _int The int to convert.
//      * @return A little endian array.
//      */
//     public static byte[] intToBytes(int _int) {
//         byte[] result = new byte[4];
//         for (int i = 0; i <= 3; i++) {
//             result[i] = (byte)(_int & 0xFF);
//             _int >>= 8;
//         }
//         return result;
//     }
// 
//     public static Map<Integer, String> printableSpansWithIndexes(byte[] bytes, int minLength, boolean filterRandom, int randomThreshold) {
// 
//         Map<Integer, String> spanPairs = new HashMap<>();
//         int[] table = new int[bytes.length];
//         int tableSize = 0;
//         int strStart, strSize;
//         byte[] byteSpan;
//         String span;
// 
// 
//         for (int i = 0; i < bytes.length; i++)
//         {
//             if (!isPrintable(bytes[i]))
//             {
//                 table[tableSize++] = i;
//             }
//         }
// 
//         for (int j = 1; j < tableSize; j++)
//         {
//             if (table[j] == 0)
//             {
//                 continue;
//             }
// 
//             strStart = table[j - 1] + 1;
//             strSize = table[j] - strStart;
// 
//             if (strSize < minLength)
//             {
//                 continue;
//             }
// 
// 
//             byteSpan = Arrays.copyOfRange(bytes, strStart, strStart + strSize);
//             span = new String(byteSpan, StandardCharsets.US_ASCII);
//             spanPairs.put(strStart, span);
//         }
// 
//         if (filterRandom)
//         {
//             //TODO: Bother with this?
//             return spanPairs;
//         }
//         else
//         {
//             return spanPairs;
//         }
//     }
// 
//     private static boolean isPrintable(byte b)
//     {
//         return (b >= 0x20 && b < 0x7F) || b == 0x0a || b == 0x0d || b == 0x09;
//     }
// }


// Path: src/com/ciphertechsolutions/io/processing/CompressionTask.java
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import javax.xml.bind.DatatypeConverter;
import com.ciphertechsolutions.io.ewf.DataChunk;
import com.ciphertechsolutions.io.processing.triage.ByteUtils;

package com.ciphertechsolutions.io.processing;




class CompressionTask implements Callable<DataChunk> {

    private final byte[] input;
    private final int compressionLevel;

    CompressionTask(byte[] toCompress, int compressionLevel) {
        input = toCompress;
        this.compressionLevel = compressionLevel;
    }

    @Override
    public DataChunk call() throws Exception {
        Deflater deflater = new Deflater(compressionLevel);
        deflater.setInput(input);
        deflater.finish();
        byte[] output = new byte[input.length + 4];
        int compressedSize = deflater.deflate(output);
        //Unlikely, but possible.
        if (compressedSize >= input.length) {
            System.arraycopy(input, 0, output, 0, input.length);
            System.arraycopy(ByteUtils.intToBytes(deflater.getAdler()), 0, output, input.length, 4);