//Compress aBitmap into byte array
        public static byte[] Compress(AccessibleBitmap source)
        {
            //Initialize
            List <int> distances    = new List <int>(); //A list containing all the lenghts of same pixels
            List <int> pixels       = new List <int>(); //A list containing all the pixels that correspond to the lengths in 'distances' list
            int        tempDistance = -1;               //The length of one run of bits with the same value, while it is not saved yet: -1 because it will be increased before the first check

            byte[] lastPixel = source.GetPixel(0, 0);   //The pixel of the last checked pixel, to compare with the current pixel: set value to the value of the first pixel so the first check will succeed

            //Loop trough all lines of pixels
            for (int y = 0; y < source.height; y++)
            {
                //Loop trough all pixels in this line
                for (int x = 0; x < source.width; x++)
                {
                    //Take value of the current pixel
                    byte[] currentPixel = source.GetPixel(x, y);

                    //If the value of the bit of this pixel matches the value of the bit of the previous pixel
                    if (currentPixel.SequenceEqual(lastPixel))
                    {
                        //Values are the same, so increase current run
                        tempDistance++;
                    }
                    else
                    {
                        //Values are not the same, so save the run
                        distances.Add(tempDistance);
                        pixels.AddRange(Array.ConvertAll(lastPixel, b => (int)b));

                        //Set the bit value for the next comparison to the bit value of this pixel
                        lastPixel = currentPixel;

                        //Reset the run length for the new run
                        tempDistance = 0;
                    }
                }
            }
            //Save the last run becouse this never happens in the loop
            distances.Add(tempDistance);
            pixels.AddRange(Array.ConvertAll(lastPixel, b => (int)b));

            //Compress the array of run lengths using different techniques
            BitStreamFIFO pixelStream = VaryingIntArrayCompressor.Compress(pixels.ToArray());

            //Compress the array of run lengths using different techniques
            BitStreamFIFO lengthStream = VaryingIntArrayCompressor.Compress(distances.ToArray());

            //Combine the compressed data of the runs with the compressed data of the pixel values, then return the BitStream
            return(BitStreamFIFO.Merge(pixelStream, lengthStream).ToByteArray());
        }
Example #2
0
        public static byte[] CompressVertical(AccessibleBitmap source)
        {
            byte[] lastpixel = null;                                // Create variable to store the last pixel
            int colorCounter = 1;                                   // Create counter for current color
            BitStreamFIFO bs = new BitStreamFIFO();                 // Create new bitstream for all the bits
            int maxCount = 0;                                       // Create variable to store the max bitcount
            Queue<PixelArray> output = new Queue<PixelArray>();     // Create list to store all the pixelvalues in

            // Write one bit to the bitstream, so the decompressor knows to decompress vertically
            bs.Write(true);

            // Iterate through every vertical row
            for (int x = 0; x < source.width; x++)
            {
                // Iterate through every pixel in the vertical row
                for (int y = 0; y < source.height; y++)
                {
                    // Check if the variable lastpixel is empty
                    if (lastpixel == null)
                    {
                        // If lastpixel is empty, set last pixel to the first pixel
                        lastpixel = source.GetPixel(x, y);
                    }
                    else
                    {
                        // If lastpixel isn't empty, compare last pixel with new pixel
                        if (lastpixel.SequenceEqual(source.GetPixel(x, y)))
                        {
                            // Pixels matched, so increase the counter value
                            colorCounter++;
                        }
                        else
                        {
                            // If the pixels don't match, add the counter with the last pixel to the output queue
                            output.Enqueue(new PixelArray(colorCounter, lastpixel));
                            // Check if the new countervalue is higher then the last one, if so set maxBitCount to that
                            if (colorCounter > maxCount)
                                maxCount = colorCounter;

                            // Reset the colorCounter and set the last pixel to the new pixel
                            colorCounter = 1;
                            lastpixel = source.GetPixel(x, y);
                        }
                    }
                }
            }

            // Add the remaining pixel(s) to the bitstream
            output.Enqueue(new PixelArray(colorCounter, lastpixel));
            // Check if the new countervalue is higher then the last one, if so set maxBitCount to that
            if (colorCounter > maxCount)
                maxCount = colorCounter;

            // Write the maxCount to the bitstream
            bs.Write((byte)Math.Ceiling(Math.Log(maxCount, 2)));

            // Add all the pixels from the queue to the bitstream
            while (output.Count > 0)
            {
                PixelArray pixel = output.Dequeue();
                bs.Write(pixel.Count, (int)Math.Ceiling(Math.Log(maxCount, 2)));
                bs.Write(pixel.Pixel);
            }

            // Return the bitsream as a byte[]
            return bs.ToByteArray();
        }