class OverlayUtils {

    protected static byte[] padToFixRowByteBoundary(byte[] unpaddedData, int rows, int cols) {
        int numRowBytes = (cols+7)/8;
        int paddedLength = rows * numRowBytes;
        if( (unpaddedData.length == paddedLength ) && (cols%8)==0 ) return unpaddedData;
        
        byte[] data = new byte[paddedLength];
        
        for(int y=0; y<rows; y++) {
            int posnPad = y*numRowBytes;
            int posnUnpad = y*cols;
            // Bits from the current byte needed
            int bits = posnUnpad % 8;
            posnUnpad /= 8;
            int prevBits = 8-bits;
            if( bits==0 ) {
                // Not only an optimization for performance - also prevents an exception if the last pixel doesn't need 
                // to overflow from the next unpadded byte...
                System.arraycopy(unpaddedData,posnUnpad,data, posnPad, numRowBytes);
                continue;
            }
            int mask = (0xFF << bits) & 0xFF;
            int nextMask = (0xFF >> prevBits) & 0xFF;
            for(int x=0; x<numRowBytes; x++) {
                try {
                    byte firstByte = (byte) ((unpaddedData[posnUnpad+x] & mask)>>bits);
                    byte secondByte = 0;
                    // The very last byte can use nothing from the next byte if there are unused bits in it
                    if( posnUnpad+x+1 < unpaddedData.length ) secondByte = (byte) ((unpaddedData[posnUnpad+x+1] & nextMask) << prevBits);
                    data[posnPad+x] = (byte) (firstByte | secondByte);
                } catch (ArrayIndexOutOfBoundsException e) {
                    ArrayIndexOutOfBoundsException newEx = new ArrayIndexOutOfBoundsException(
                            "Did not find enough source data ("+unpaddedData.length+") in overlay to pad data for " 
                            + rows + " rows, " 
                            + cols + "columns");
                    newEx.initCause(e);
                    throw newEx;
                }
            }
        }
        
        return data;
    }

}