Exemple #1
0
        //Compress integer array into BitStream
        public static BitStreamFIFO Compress(int[] source)
        {
            //Compress the array of integers using all different compression techniques, where possible at the same time
            BitStreamFIFO[] compressionTechniques = new BitStreamFIFO[2];
            Parallel.For(0, compressionTechniques.Length, (i, state) =>
            {
                switch (i)
                {
                //Huffmann: generate a dictionary of all used integer values where more frequent values have a code with less bits
                case 0:
                    compressionTechniques[i] = HuffmanIntArrayCompressor.Compress(source);
                    break;

                //Variable int length: save smaller integers with less bits than bigger integers
                case 1:
                    compressionTechniques[i] = VaryingIntLengthIntArrayCompressor.Compress(source);
                    break;

                    //To add a compression technique, add a new case like the existing ones and increase the length of new byte[??][]
                }
            });

            //Choose the smallest compression type

            //Initialize
            int smallestID   = 0;               //The ID of the smallest compression type
            int smallestSize = int.MaxValue;    //The size ofthe smallest compression type: int.MaxValue is assigned to make sure that the first compression to be checked will be smaaller than this value

            //Loop trough all saved compression techniques
            for (int i = 0; i < compressionTechniques.Length; i++)
            {
                //If the current technique is smaller than the smallest technique which has been checked
                if (compressionTechniques[i].Length < smallestSize)
                {
                    //Mark this technique as smallest
                    smallestSize = compressionTechniques[i].Length;
                    smallestID   = i;
                }
            }

            //Create a new BitStream to write necessary information for the decompressor
            BitStreamFIFO compressionInfo = new BitStreamFIFO();

            //Calculate the amount of bits needed to save the total length in bits of the compressed data
            int lengthSaveLength = (int)Math.Ceiling(Math.Log(smallestSize, 2) / 8);

            //Write data to the compression info
            compressionInfo.Write(smallestID, 2);                       //The compression technique used
            compressionInfo.Write(lengthSaveLength, 6);                 //The amount of bits needed to save the total length in bits of the compressed data
            compressionInfo.Write(smallestSize, lengthSaveLength * 8);  //The total length in bits of the compressed data

            //Merge the info about the compression type with the compressed data & return
            return(BitStreamFIFO.Merge(compressionInfo, compressionTechniques[smallestID]));
        }
        //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());
        }
        //Compress aBitmap into byte array
        public static BitStreamFIFO Compress(AccessibleBitmapBitwise source, int bitLayer)
        {
            //Initialize
            List <int> distances    = new List <int>();                   //A list containing all the lenghts of same bits
            int        tempDistance = -1;                                 //The length of one run of bits with the same value, while it is not saved yet: -1 becouse it will be increased before the first check
            bool       lastVal      = source.GetPixelBit(0, 0, bitLayer); //The bit value 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
                    bool currentBool = source.GetPixelBit(x, y, bitLayer);

                    //If the value of the bit of this pixel matches the value of the bit of the previous pixel
                    if (currentBool == lastVal)
                    {
                        //Values are the same, so increase current run
                        tempDistance++;
                    }
                    else
                    {
                        //Values are not the same, so save the run
                        distances.Add(tempDistance);

                        //Set the bit value for the next comparison to the bit value of this pixel
                        lastVal = currentBool;

                        //Reset the run length for the new run
                        tempDistance = 0;
                    }
                }
            }
            //Save the last run becouse this never happens in the loop
            distances.Add(tempDistance);

            //Save the bit value of the first pixel, because the decompressor needs to know this
            bool initialVal = source.GetPixelBit(0, 0, bitLayer);

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

            //Combine the inititial bit value with the compressed data of the runs, then return the BitStream
            return(BitStreamFIFO.Merge(new BitStreamFIFO(new bool[] { initialVal }), bitStream));
        }
        //Compress aBitmap into byte array
        public static BitStreamFIFO Compress(AccessibleBitmapBitwise source, int bitLayer)
        {
            //Initialize vars
            BitStreamFIFO bitStream    = new BitStreamFIFO();
            List <int>    distances    = new List <int>();
            int           tempDistance = -1;
            bool          lastVal      = source.GetPixelBit(0, 0, bitLayer);

            //Iterate trough pixels
            for (int y = 0; y < source.height; y++)
            {
                for (int x = 0; x < source.width; x++)
                {
                    //Take value of pixel & compare with previous value
                    bool currentBool = source.GetPixelBit(x, y, bitLayer);
                    if (currentBool == lastVal)
                    {
                        //Values are the same, so increase current run
                        tempDistance++;
                    }
                    else
                    {
                        //Values are not the same, so save the run and create a new one
                        distances.Add(tempDistance);
                        lastVal      = currentBool;
                        tempDistance = 0;
                    }
                }
            }
            //Save the last run becouse this never happens in the loop
            distances.Add(tempDistance);


            bool initialVal = source.GetPixelBit(0, 0, bitLayer);

            bitStream.Write(initialVal);

            BitStreamFIFO output = BitStreamFIFO.Merge(bitStream, VaryingIntArrayCompressor.Compress(distances.ToArray()));

            return(output);
        }
Exemple #5
0
        //Compress aBitmap into byte array
        public static byte[] Compress(AccessibleBitmapBytewise source, int byteLayer)
        {
            //Loop trough all layers of bits, where possible at the same time
            AccessibleBitmapBitwise aBitmap = new AccessibleBitmapBitwise(source);

            BitStreamFIFO[] byteLayers = new BitStreamFIFO[8];
            Parallel.For(byteLayer * 8, byteLayer * 8 + 8, (z, state) => //for(int z = byteLayer * 8; z < byteLayer * 8 + 8; z++)
            {
                //Compress image using all different compression techniques, where possible at the same time
                BitStreamFIFO[] compressionTechniques = new BitStreamFIFO[4];
                Parallel.For(0, compressionTechniques.Length, (i, state2) =>
                {
                    switch (i)
                    {
                    //Uncompressed (only used if no compression technique is smaller)
                    case 0:
                        compressionTechniques[i] = UncompressedBitmapCompressorBitwise.Compress(aBitmap, z);
                        break;

                    //Compress bit channel as an integer array using several techniques, using 8-bit integers
                    case 1:
                        compressionTechniques[i] = ByteArrayCompressorBitwise.Compress(aBitmap, z);
                        break;

                    //Run length compression: save the length of a sequence of bit values instead of saving them seperately
                    case 2:
                        compressionTechniques[i] = RunLengthEncodingCompressorBitwise.Compress(aBitmap, z);
                        break;

                    //Run length compression vertical: run length compression, but scan the pixels horizontally, becouse with some images this yields better results
                    case 3:
                        compressionTechniques[i] = RunLengthEncodingCompressorVerticalBitwise.Compress(aBitmap, z);
                        break;

                        //To add a compression technique, add a new case like the existing ones and increase the length of new byte[??][]
                    }
                });


                //Choose the smallest compression type

                //Initialize
                int smallestID   = 0;               //The ID of the smallest compression type
                int smallestSize = int.MaxValue;    //The size ofthe smallest compression type: int.MaxValue is assigned to make sure that the first compression to be checked will be smaaller than this value

                //Loop trough all saved compression techniques
                for (int i = 0; i < compressionTechniques.Length; i++)
                {
                    //If the current technique is smaller than the smallest technique which has been checked
                    if (compressionTechniques[i].Length < smallestSize)
                    {
                        //Mark this technique as smallest
                        smallestSize = compressionTechniques[i].Length;
                        smallestID   = i;
                    }
                }

                //Merge the number of the compression type of this layer with corresponding bitStream
                BitStreamFIFO tmpStream = new BitStreamFIFO();
                tmpStream.Write(smallestID, 3);    //This 3-bit integer indicates which technique the decompressor should use, and should be before the image data
                byteLayers[z % 8] = BitStreamFIFO.Merge(tmpStream, compressionTechniques[smallestID]);
            });

            //Combine all bitstreams & convert the result to a byte array
            byte[] outputStream = BitStreamFIFO.Merge(byteLayers).ToByteArray();

            //Return the data of all the bit channels combined
            return(outputStream);
        }