private void StartEvolution(Bitmap input)
        {
            Pixel[] sourcePixels = SetupSourceColorMatrix(input);
            if (currentDrawing == null)
                currentDrawing = GetNewInitializedDrawing();
            lastSelected = 0;
            int freq = 0;
            double target= (32 * 32 * 3D * (input.Height ) * (input.Width ));
            double minTarget = (64 * 64 * 3D * (input.Height) * (input.Width));
            writeConsolas("target: " + target);

            DateTime startTime2 = DateTime.Now;
            while (isRunning)
            {
                DnaDrawing newDrawing;
                lock (currentDrawing)
                {
                    newDrawing = currentDrawing.Clone();
                }
                newDrawing.Mutate();

                if (newDrawing.IsDirty) //idk - this deceides whether or not to change the drawing i guess
                {

                    generation++;

                    NewFitnessCalculator test = new NewFitnessCalculator();
                    double newErrorLevel = test.GetDrawingFitness(newDrawing, sourcePixels);
                    test.Dispose();

                    if ((errorLevel <= target) || (((DateTime.Now - startTime2).TotalSeconds > 60)&&(newErrorLevel <=minTarget)))
                    {
                        writeConsolas("shapes done: " + newErrorLevel + "in: " + (DateTime.Now - startTime2));
                        DateTime startTime3 = DateTime.Now;
                        isRunning = false;
                        int[,] DiffArray = new int[Tools.MaxWidth * Tools.MaxHeight, 4];
                        int[,] RefArray = new int[Tools.MaxWidth * Tools.MaxHeight, 5];
                        Bitmap _bmp;
                        Graphics _g;
                        _bmp = new System.Drawing.Bitmap(Tools.MaxWidth, Tools.MaxHeight);
                        _g = Graphics.FromImage(_bmp);
                        Renderer.Render(newDrawing, _g, 1);
                        BitmapData bd = _bmp.LockBits(new System.Drawing.Rectangle(0, 0, Tools.MaxWidth, Tools.MaxHeight), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                        int arraycounter = 0;
                        unchecked
                        {
                            unsafe
                            {
                                fixed (Pixel* psourcePixels = sourcePixels)
                                {
                                    Pixel* p1 = (Pixel*)bd.Scan0.ToPointer();
                                    Pixel* p2 = psourcePixels;
                                    for (int i = sourcePixels.Length; i > 0; i--, p1++, p2++)
                                    {
                                        int a = p2->A - p1->A;
                                        int r = p2->R - p1->R;
                                        int g = p2->G - p1->G;
                                        int b = p2->B - p1->B;
                                        DiffArray[arraycounter, 0] = a;
                                        DiffArray[arraycounter, 1] = r;
                                        DiffArray[arraycounter, 2] = g;
                                        DiffArray[arraycounter, 3] = b;
                                        arraycounter++;
                                    }
                                }
                            }
                        }
                        writeConsolas("DiffArray done: " + newErrorLevel + "in: " + (DateTime.Now - startTime3));
                        //RefArray = startReference(DiffArray);
                        for (int w = 0, e=0; w<RefArray.Length/5;w++)
                        {
                            if (((RefArray[w, 0] != RefArray[w - RefArray[w, 4], 0]) || (RefArray[w, 1] != RefArray[w - RefArray[w, 4], 1]) || (RefArray[w, 2] != RefArray[w - RefArray[w, 4], 2]) || (RefArray[w - RefArray[w, 4], 3] != RefArray[w, 3])))
                            {
                                //Console.WriteLine(w + ":" + (e));
                                e++;
                            }
                        }
                        Console.WriteLine("returned");

                        _bmp.UnlockBits(bd);
                        double total= 0D;
                        for (int i = 0; i < DiffArray.Length/4; i++)
                        {
                            total += Math.Abs(DiffArray[i, 0]);
                            total += Math.Abs(DiffArray[i, 1]);
                            total += Math.Abs(DiffArray[i, 2]);
                            total += Math.Abs(DiffArray[i, 3]);
                        }
                        writeConsolas("done with average difference: " + total / DiffArray.Length);
                        _bmp.Save("hopefully.png", System.Drawing.Imaging.ImageFormat.Png);
                        //byte[] result = {0,1};
                        //Console.WriteLine(result[0]);

                        List<BitArray> BitList = new List<BitArray>();
                        BitList.Add(WriteBits(Tools.MaxWidth, 16));
                        Console.WriteLine(Tools.MaxWidth.ToString());
                        BitList.Add(WriteBits(Tools.MaxHeight, 16));
                        BitList.Add(WriteBits(Tools.avgColour.R, 8));
                        BitList.Add(WriteBits(Tools.avgColour.G, 8));
                        BitList.Add(WriteBits(Tools.avgColour.B, 8));
                        BitList.Add(WriteBits(newDrawing.Polygons.Count, 10));
                        int q=0;
                        foreach (DnaPolygon polygon in newDrawing.Polygons)
                        {
                            BitList.Add(WriteBits(polygon.Points.Count, 5));
                            BitList.Add(WriteBits(polygon.Brush.Alpha, 8));
                            BitList.Add(WriteBits(polygon.Brush.Red, 8));
                            BitList.Add(WriteBits(polygon.Brush.Green, 8));
                            BitList.Add(WriteBits(polygon.Brush.Blue, 8));
                            foreach (DnaPoint point in polygon.Points)
                            {
                                BitList.Add(WriteBits(point.X, 12));
                                BitList.Add(WriteBits(point.Y, 12));
                            }
                            Console.WriteLine(q.ToString());
                            q++;
                        }
                        //BitList.Add(WriteBits(Tools.MaxWidth, 1));
                        for (int k = 0, c = 0; k < DiffArray.Length / 4; k++, c++)
                        {
                            if (RefArray[k, 4] != 0)
                            {
                                BitList.Add(WriteBits(1, 1));
                                BitList.Add(WriteBits(RefArray[k, 4],11));
                            }
                            else
                            {
                                BitList.Add(WriteBits(0, 1));
                                //BitList.Add(WriteBits(neg(DiffArray[k, 0]), 1));
                                //BitList.Add(WriteBits(BitSize(DiffArray[k, 0]), 2));
                                //BitList.Add(WriteBits(neg(DiffArray[k, 1]), 1)); //hopefully i don't need to comment this
                                //BitList.Add(WriteBits(BitSize(DiffArray[k, 1]), 2));
                                //BitList.Add(WriteBits(neg(DiffArray[k, 2]), 1));
                                //BitList.Add(WriteBits(BitSize(DiffArray[k, 2]), 2));
                                //BitList.Add(WriteBits(neg(DiffArray[k, 3]), 1));
                                //BitList.Add(WriteBits(BitSize(DiffArray[k, 3]), 2));
                                BitList.Add(WriteBits(DiffArray[k, 0]+256, 9));//BitSize(DiffArray[k, 0]) + 4));
                                BitList.Add(WriteBits(DiffArray[k, 1]+256, 9));//BitSize(DiffArray[k, 1]) + 4));
                                BitList.Add(WriteBits(DiffArray[k, 2]+256, 9));//BitSize(DiffArray[k, 2]) + 4));
                                BitList.Add(WriteBits(DiffArray[k, 3]+256, 9));//BitSize(DiffArray[k, 3]) + 4));
                            }
                        }
                        Console.WriteLine("done writing to bits");
                        int totalBitCount = 0;
                        foreach (BitArray array in BitList)
                        {
                            totalBitCount += array.Count;
                        }
                        BitArray allBits = new BitArray(totalBitCount);
                        int abcounter = 0;
                        foreach (BitArray array in BitList)
                        {
                            foreach (Boolean bit in array)
                            {
                                allBits[abcounter] = bit;
                                abcounter++;
                            }
                        }
                        byte[] result = ToByteArray(allBits);
                        Console.WriteLine(result.Length.ToString());
                        QuickLZ qlz = new QuickLZ();
                        byte[] compressed = qlz.Compress(result);
                        byte[] decompressed = qlz.Decompress(compressed);
                        //byte[] result = new byte[RefArray.Length * 5 * sizeof(int)];
                        //Buffer.BlockCopy(RefArray, 0, result, 0, result.Length/5);
                        File.WriteAllBytes("output.eica", compressed);
                        File.WriteAllBytes("output2.eica", decompressed);

                        Bitmap _bmp2 = new System.Drawing.Bitmap(Tools.MaxWidth, Tools.MaxHeight);
                        int arraycounter2 = 0;
                        for (int y = 0; y < Tools.MaxHeight; y++)
                        {
                            for (int x = 0; x < Tools.MaxWidth; x++)
                            {
                                System.Drawing.Color c1 = _bmp.GetPixel(x, y);
                                int a = c1.A + DiffArray[arraycounter2, 0];
                                int r = c1.R + DiffArray[arraycounter2, 1];
                                int g = c1.G + DiffArray[arraycounter2, 2];
                                int b = c1.B + DiffArray[arraycounter2, 3];
                                System.Drawing.Color c3 = System.Drawing.Color.FromArgb(a, r, g, b);
                                _bmp2.SetPixel(x, y, c3);
                                arraycounter2++;
                            }
                        }
                        _bmp2.Save("success.png", System.Drawing.Imaging.ImageFormat.Png);
                        writeConsolas("saving done: " + newErrorLevel + "in: " + (DateTime.Now - startTime3));

                        //for (int k = 0; k < RefArray.Length / 5; k++)
                        //{
                        //    if (RefArray[k, 4] != 0)
                        //    {
                        //        int whatervertest = RefArray[k, 4];
                        //        RefArray[k, 0] = RefArray[k - Math.Abs(RefArray[k, 4]), 0];
                        //        RefArray[k, 1] = RefArray[k - Math.Abs(RefArray[k, 4]), 1];
                        //        RefArray[k, 2] = RefArray[k - Math.Abs(RefArray[k, 4]), 2];
                        //        RefArray[k, 3] = RefArray[k - Math.Abs(RefArray[k, 4]), 3];
                        //    }
                        //}

                        //Bitmap _bmp2 = new System.Drawing.Bitmap(Tools.MaxWidth, Tools.MaxHeight);
                        //int arraycounter2 = 0;
                        //for (int y = 0; y < Tools.MaxHeight; y++)
                        //{
                        //    for (int x = 0; x < Tools.MaxWidth; x++)
                        //    {
                        //        System.Drawing.Color c1 = _bmp.GetPixel(x, y);
                        //        int a = c1.A + RefArray[arraycounter2, 0];
                        //        int r = c1.R + RefArray[arraycounter2, 1];
                        //        int g = c1.G + RefArray[arraycounter2, 2];
                        //        int b = c1.B + RefArray[arraycounter2, 3];
                        //        System.Drawing.Color c3 = System.Drawing.Color.FromArgb(a, r, g, b);
                        //        _bmp2.SetPixel(x, y, c3);
                        //        arraycounter2++;
                        //    }
                        //}
                        //_bmp2.Save("success.png", System.Drawing.Imaging.ImageFormat.Png);
                    }
                    if (newErrorLevel <= errorLevel)
                    {
                        selected++;
                        lock (currentDrawing)
                        {
                            currentDrawing = newDrawing;
                        }
                        errorLevel = newErrorLevel;

                        if (freq == 100)
                        {
                            writeConsolas("next gen created with error level: " + errorLevel);
                            freq = 0;
                        }
                        freq++;
                    }
                }
                //else, discard new drawing
            }
            return;
        }
        public void decompress()
        {
            QuickLZ qlz = new QuickLZ();
            byte[] decompressed = qlz.Decompress(File.ReadAllBytes(InputFile));
            Console.WriteLine("dec" + decompressed.Length.ToString());
            BitArray bits = new BitArray(decompressed);
            Console.WriteLine("bits" + bits.Length.ToString());
            int progress = 0;
            BitArray width = new BitArray(16); //Max width
            bitArrayCopy(bits, progress, width, 0, 16);
            Tools.MaxWidth = unwritebits(width); //create maxwidth
            progress += 16;
            BitArray height = new BitArray(16); //Max height
            bitArrayCopy(bits, progress, height, 0, 16);
            Tools.MaxHeight = unwritebits(height); //create maxheight
            progress += 16;
            BitArray avgreds = new BitArray(8); //red colour average
            bitArrayCopy(bits, progress, avgreds, 0, 8);
            int avgred = unwritebits(avgreds);
            progress += 8;
            BitArray avggreens = new BitArray(8); //green colour average
            bitArrayCopy(bits, progress, avggreens, 0, 8);
            int avggreen = unwritebits(avggreens);
            progress += 8;
            BitArray avgblues = new BitArray(8); //blue colour average
            bitArrayCopy(bits, progress, avgblues, 0, 8);
            int avgblue = unwritebits(avgblues);
            progress += 8;
            Tools.avgColour = System.Drawing.Color.FromArgb(avgred, avggreen, avgblue); //create average colour
            DnaDrawing newDrawing = new DnaDrawing(); //Create dnadrawing
            //newDrawing.Init();
            BitArray polynumbers = new BitArray(10); //number of polygons
            bitArrayCopy(bits, progress, polynumbers, 0, 10);
            int polynumber = unwritebits(polynumbers);
            progress += 10;
            newDrawing.Polygons = new List<DnaPolygon>();
            for (int i = 0; i < polynumber; i++)
            {
                Console.WriteLine(i);
                DnaPolygon polygon = new DnaPolygon(); //create dnapolygon
                polygon.Points = new List<DnaPoint>();
                BitArray pointnumbers = new BitArray(5); //number of points
                bitArrayCopy(bits, progress, pointnumbers, 0, 5);
                int pointnumber = unwritebits(pointnumbers);
                progress += 5;
                BitArray alphas = new BitArray(8); //alpha colour
                bitArrayCopy(bits, progress, alphas, 0, 8);
                int alpha = unwritebits(alphas);
                progress += 8;
                BitArray reds = new BitArray(8); //red colour
                bitArrayCopy(bits, progress, reds, 0, 8);
                int red = unwritebits(reds);
                progress += 8;
                BitArray greens = new BitArray(8); //green colour
                bitArrayCopy(bits, progress, greens, 0, 8);
                int green = unwritebits(greens);
                progress += 8;
                BitArray blues = new BitArray(8); //blue colour
                bitArrayCopy(bits, progress, blues, 0, 8);
                int blue = unwritebits(blues);
                progress += 8;
                DnaBrush brush = new DnaBrush(); //create dnabrush
                brush.Alpha=alpha;
                brush.Red = red;
                brush.Green = green;
                brush.Blue=blue;
                polygon.Brush=brush; //assign brush
                for (int j = 0; j < pointnumber; j++)
                {
                    DnaPoint point = new DnaPoint();
                    BitArray Xs = new BitArray(12); //x position
                    bitArrayCopy(bits, progress, Xs, 0, 12);
                    int x = unwritebits(Xs);
                    progress += 12;
                    point.X = x;
                    BitArray Ys = new BitArray(12); //y position
                    bitArrayCopy(bits, progress, Ys, 0, 12);
                    int y = unwritebits(Ys);
                    progress += 12;
                    point.Y = y;
                    polygon.Points.Add(point);
                }
                newDrawing.Polygons.Add(polygon);
            }
            int[,] DiffArray = new int[Tools.MaxWidth * Tools.MaxWidth, 4];
            int[,] refArray = new int[Tools.MaxWidth * Tools.MaxWidth, 5];
            for (int i = 0; i < Tools.MaxWidth * Tools.MaxWidth; i++)
            {
                BitArray firsts = new BitArray(1); //normal or reference
                bitArrayCopy(bits, progress, firsts, 0, 1);
                int first = unwritebits(firsts);
                progress += 1;
                if (first == 1)
                {
                    BitArray reffs = new BitArray(11); //reference number
                    bitArrayCopy(bits, progress, reffs, 0, 11);
                    int reff = unwritebits(reffs);
                    progress += 11;
                    refArray[i,4]=reff;
                }
                else
                {
                    //BitArray asizes = new BitArray(3); //alpha size
                    //bitArrayCopy(bits, progress, asizes, 0, 3);
                    int asize = 9;//unwritebits(asizes);
                    //progress += 3;
                    //BitArray rsizes = new BitArray(3); //red size
                    //bitArrayCopy(bits, progress, rsizes, 0, 3);
                    int rsize = 9;//unwritebits(rsizes);
                    //progress += 3;
                    //BitArray gsizes = new BitArray(3); //green size
                    //bitArrayCopy(bits, progress, gsizes, 0, 3);
                    int gsize = 9;//unwritebits(gsizes);
                    //progress += 3;
                    //BitArray bsizes = new BitArray(3); //blue size
                    //bitArrayCopy(bits, progress, bsizes, 0, 3);
                    int bsize = 9;//unwritebits(bsizes);
                    //progress += 3;

                    BitArray a = new BitArray(asize); //alpha
                    bitArrayCopy(bits, progress, a, 0, asize);
                    int alpha = unwritebits(a);
                    progress += asize;
                    DiffArray[i, 0] = alpha-256;
                    BitArray r = new BitArray(rsize); //red
                    bitArrayCopy(bits, progress, r, 0, rsize);
                    int red = unwritebits(r);
                    progress += rsize;
                    DiffArray[i, 1] = red-256;
                    BitArray g = new BitArray(gsize); //green
                    bitArrayCopy(bits, progress, g, 0, gsize);
                    int green = unwritebits(g);
                    progress += gsize;
                    DiffArray[i, 2] = green-256;
                    BitArray b = new BitArray(bsize); //blue
                    bitArrayCopy(bits, progress, b, 0, bsize);
                    int blue = unwritebits(b);
                    progress += bsize;
                    DiffArray[i, 3] = blue-256;
                }
            }
            //int[,] fullArray = (int[,]) refArray.Clone();
            for (int k = 0; k < refArray.Length / 5; k++)
            {
                if (refArray[k, 4] != 0)
                {
                    DiffArray[k, 0] = refArray[k - refArray[k, 4], 0];
                    DiffArray[k, 1] = refArray[k - refArray[k, 4], 1];
                    DiffArray[k, 2] = refArray[k - refArray[k, 4], 2];
                    DiffArray[k, 3] = refArray[k - refArray[k, 4], 3];
                    Console.WriteLine(refArray[k, 1]);
                }
            }

            Console.WriteLine(newDrawing.Polygons.Count);
            Console.WriteLine("done with drawing");

            Bitmap _bmp;
            Graphics _g;
            _bmp = new System.Drawing.Bitmap(Tools.MaxWidth, Tools.MaxHeight);
            _g = Graphics.FromImage(_bmp);
            Renderer.Render(newDrawing, _g, 1);
            BitmapData bd = _bmp.LockBits(new System.Drawing.Rectangle(0, 0, Tools.MaxWidth, Tools.MaxHeight), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            _bmp.Save("finally.png", System.Drawing.Imaging.ImageFormat.Png);
            _bmp.UnlockBits(bd);

            Bitmap _bmp2 = new System.Drawing.Bitmap(Tools.MaxWidth, Tools.MaxHeight);
            int arraycounter2 = 0;
            for (int y = 0; y < Tools.MaxHeight; y++)
            {
                for (int x = 0; x < Tools.MaxWidth; x++)
                {
                    System.Drawing.Color c1 = _bmp.GetPixel(x, y);
                    int a = c1.A + DiffArray[arraycounter2, 0];
                    int r = c1.R + DiffArray[arraycounter2, 1];
                    int g = c1.G + DiffArray[arraycounter2, 2];
                    int b = c1.B + DiffArray[arraycounter2, 3];
                    System.Drawing.Color c3 = System.Drawing.Color.FromArgb(a, r, g, b);
                    _bmp2.SetPixel(x, y, c3);
                    arraycounter2++;
                }
            }
            _bmp2.Save("success.png", System.Drawing.Imaging.ImageFormat.Png);
            System.Diagnostics.Process.Start(@"success.png");
        }