// Path: src/lattice/LongLattice.java
// public static class Run {
//     public short x;
//     public short y;
//     public short length;
// 
//     public Run(short x, short y, short length) {
//         this.x = x;
//         this.y = y;
//         this.length = length;
//     }
// }
// 
// Path: src/pipeline/Encoder.java
// public class Encoder {
// //@formatter:on
//     /**
//      * @author Aleksejs Truhans
//      */
//     public static class Statistics {
//         private int compressedHeaderSizeBytes;
//         private int compressedLatticeSizeBytes;
//         private int remainderBitsSizeBytes;
//         private int NanRunsSizeBytes;
// 
//         public int getCompressedHeaderSizeBytes() {
//             return compressedHeaderSizeBytes;
//         }
// 
//         public int getCompressedLatticeSizeBytes() {
//             return compressedLatticeSizeBytes;
//         }
// 
//         public int getRemainderBitsSizeBytes() {
//             return remainderBitsSizeBytes;
//         }
// 
//         public int getNanRunsSizeBytes() {
//             return NanRunsSizeBytes;
//         }
//     }
// 
//     private final LongLattice source;
//     private final Statistics statistics = new Statistics();
// 
//     public Encoder(LongLattice source) {
//         this.source = source;
//     }
// 
//     public Encoder(BufferedImage sourceImage) {
//         this(representImageAsHexagonalLattice(sourceImage));
//     }
// 
//     public byte[] encode() {
//         List<byte[]> data = new LinkedList<byte[]>();
//         HexByteRavelet ravelet = new HexByteRavelet(source);
//         ravelet.encode();
// 
//         byte[] compressedHeader = Compressor.compress(generateHeader(ravelet));
//         statistics.compressedHeaderSizeBytes = compressedHeader.length;
//         data.add(ArrayUtils.intAsByteArray(compressedHeader.length));
//         data.add(compressedHeader);
// 
//         byte[] compressedLattice = Compressor.compress(ravelet.getDataAsByteStream());
//         statistics.compressedLatticeSizeBytes = compressedLattice.length;
//         data.add(ArrayUtils.intAsByteArray(compressedLattice.length));
//         data.add(compressedLattice);
// 
//         List<Run> nanRuns = ravelet.getNanRuns();
//         byte[] nanRunsBytes = generateNanRuns(nanRuns);
//         statistics.NanRunsSizeBytes = nanRunsBytes.length;
//         data.add(ArrayUtils.intAsByteArray(nanRunsBytes.length));
//         data.add(nanRunsBytes);
// 
//         byte[] remainderBits = Compressor.compress(ravelet.getReminderBitStream());
//         statistics.remainderBitsSizeBytes = remainderBits.length;
//         data.add(ArrayUtils.intAsByteArray(remainderBits.length));
//         data.add(remainderBits);
// 
//         return ArrayUtils.joinArrays(data);
//     }
// 
//     public static byte[] generateNanRuns(List<LongLattice.Run> nanRuns) {
//         try {
//             ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
//             DataOutputStream dataOut = new DataOutputStream(byteOut);
// 
//             for (Run run : nanRuns) {
//                 dataOut.writeShort((short) run.x);
//                 dataOut.writeShort((short) run.y);
//                 dataOut.writeShort((short) run.length);
//             }
// 
//             return byteOut.toByteArray();
//         } catch (IOException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     public static LongLattice representImageAsHexagonalLattice(BufferedImage sourceImage) {
//         double[][] source = ImageUtils.imageRasterToDoubleArray(sourceImage);
//         return representImageAsHexagonalLattice(source);
//     }
// 
//     public static LongLattice representImageAsHexagonalLattice(double[][] source) {
//         DoubleLattice hexDoubleLattice = H2O.o2h(source);
//         LongLattice hexLongLattice = LongLattice.fromLattice(hexDoubleLattice);
//         return hexLongLattice;
//     }
// 
//     public static byte[] generateHeader(LongLattice lattice) {
//         try {
//             ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
//             DataOutputStream dataOut = new DataOutputStream(byteOut);
// 
//             dataOut.writeShort((short) lattice.ox);
//             dataOut.writeShort((short) lattice.oy);
//             dataOut.writeShort((short) lattice.getData()[0].length);
//             dataOut.writeShort((short) lattice.getData().length);
//             dataOut.writeDouble(lattice.min);
//             dataOut.writeDouble(lattice.factor);
// 
//             short[][] NANPositions = lattice.getNANPositionStream();
//             for (short a[] : NANPositions) {
//                 dataOut.writeShort(a[0]);
//                 dataOut.writeShort(a[1]);
//             }
//             return byteOut.toByteArray();
//         } catch (IOException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     public Statistics getStatistics() {
//         return statistics;
//     }
// 
//     public LongLattice getLattice() {
//         return source;
//     }
// 
// }


import static org.junit.Assert.assertArrayEquals;
import java.util.Arrays;
import java.util.List;
import lattice.LongLattice.Run;
import org.junit.Test;
import pipeline.Encoder;
package test.pipeline;







public class EncoderTest {

    @Test
    public final void testGenerateNanRuns() {
        //@formatter:off
        List<Run> source = Arrays.asList(new Run[] { 
                new Run((short)3,(short)1,(short)2), new Run((short)2,(short)2,(short)1) 
        } ); 

        byte[] expected = {0, 3, 0, 1, 0, 2, 0, 2, 0, 2, 0, 1};
        //@formatter:on

// Path: src/lattice/LongLattice.java
// public static class Run {
//     public short x;
//     public short y;
//     public short length;
// 
//     public Run(short x, short y, short length) {
//         this.x = x;
//         this.y = y;
//         this.length = length;
//     }
// }
// 
// Path: src/pipeline/Encoder.java
// public class Encoder {
// //@formatter:on
//     /**
//      * @author Aleksejs Truhans
//      */
//     public static class Statistics {
//         private int compressedHeaderSizeBytes;
//         private int compressedLatticeSizeBytes;
//         private int remainderBitsSizeBytes;
//         private int NanRunsSizeBytes;
// 
//         public int getCompressedHeaderSizeBytes() {
//             return compressedHeaderSizeBytes;
//         }
// 
//         public int getCompressedLatticeSizeBytes() {
//             return compressedLatticeSizeBytes;
//         }
// 
//         public int getRemainderBitsSizeBytes() {
//             return remainderBitsSizeBytes;
//         }
// 
//         public int getNanRunsSizeBytes() {
//             return NanRunsSizeBytes;
//         }
//     }
// 
//     private final LongLattice source;
//     private final Statistics statistics = new Statistics();
// 
//     public Encoder(LongLattice source) {
//         this.source = source;
//     }
// 
//     public Encoder(BufferedImage sourceImage) {
//         this(representImageAsHexagonalLattice(sourceImage));
//     }
// 
//     public byte[] encode() {
//         List<byte[]> data = new LinkedList<byte[]>();
//         HexByteRavelet ravelet = new HexByteRavelet(source);
//         ravelet.encode();
// 
//         byte[] compressedHeader = Compressor.compress(generateHeader(ravelet));
//         statistics.compressedHeaderSizeBytes = compressedHeader.length;
//         data.add(ArrayUtils.intAsByteArray(compressedHeader.length));
//         data.add(compressedHeader);
// 
//         byte[] compressedLattice = Compressor.compress(ravelet.getDataAsByteStream());
//         statistics.compressedLatticeSizeBytes = compressedLattice.length;
//         data.add(ArrayUtils.intAsByteArray(compressedLattice.length));
//         data.add(compressedLattice);
// 
//         List<Run> nanRuns = ravelet.getNanRuns();
//         byte[] nanRunsBytes = generateNanRuns(nanRuns);
//         statistics.NanRunsSizeBytes = nanRunsBytes.length;
//         data.add(ArrayUtils.intAsByteArray(nanRunsBytes.length));
//         data.add(nanRunsBytes);
// 
//         byte[] remainderBits = Compressor.compress(ravelet.getReminderBitStream());
//         statistics.remainderBitsSizeBytes = remainderBits.length;
//         data.add(ArrayUtils.intAsByteArray(remainderBits.length));
//         data.add(remainderBits);
// 
//         return ArrayUtils.joinArrays(data);
//     }
// 
//     public static byte[] generateNanRuns(List<LongLattice.Run> nanRuns) {
//         try {
//             ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
//             DataOutputStream dataOut = new DataOutputStream(byteOut);
// 
//             for (Run run : nanRuns) {
//                 dataOut.writeShort((short) run.x);
//                 dataOut.writeShort((short) run.y);
//                 dataOut.writeShort((short) run.length);
//             }
// 
//             return byteOut.toByteArray();
//         } catch (IOException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     public static LongLattice representImageAsHexagonalLattice(BufferedImage sourceImage) {
//         double[][] source = ImageUtils.imageRasterToDoubleArray(sourceImage);
//         return representImageAsHexagonalLattice(source);
//     }
// 
//     public static LongLattice representImageAsHexagonalLattice(double[][] source) {
//         DoubleLattice hexDoubleLattice = H2O.o2h(source);
//         LongLattice hexLongLattice = LongLattice.fromLattice(hexDoubleLattice);
//         return hexLongLattice;
//     }
// 
//     public static byte[] generateHeader(LongLattice lattice) {
//         try {
//             ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
//             DataOutputStream dataOut = new DataOutputStream(byteOut);
// 
//             dataOut.writeShort((short) lattice.ox);
//             dataOut.writeShort((short) lattice.oy);
//             dataOut.writeShort((short) lattice.getData()[0].length);
//             dataOut.writeShort((short) lattice.getData().length);
//             dataOut.writeDouble(lattice.min);
//             dataOut.writeDouble(lattice.factor);
// 
//             short[][] NANPositions = lattice.getNANPositionStream();
//             for (short a[] : NANPositions) {
//                 dataOut.writeShort(a[0]);
//                 dataOut.writeShort(a[1]);
//             }
//             return byteOut.toByteArray();
//         } catch (IOException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     public Statistics getStatistics() {
//         return statistics;
//     }
// 
//     public LongLattice getLattice() {
//         return source;
//     }
// 
// }


// Path: src/test/pipeline/EncoderTest.java
import static org.junit.Assert.assertArrayEquals;
import java.util.Arrays;
import java.util.List;
import lattice.LongLattice.Run;
import org.junit.Test;
import pipeline.Encoder;

package test.pipeline;







public class EncoderTest {

    @Test
    public final void testGenerateNanRuns() {
        //@formatter:off
        List<Run> source = Arrays.asList(new Run[] { 
                new Run((short)3,(short)1,(short)2), new Run((short)2,(short)2,(short)1) 
        } ); 

        byte[] expected = {0, 3, 0, 1, 0, 2, 0, 2, 0, 2, 0, 1};
        //@formatter:on

        byte[] actual = Encoder.generateNanRuns(source); 