Example #1
0
        //Decompress byte array into aBitmap with help of width, length and bitdepth
        public static AccessibleBitmapBytewise Decompress(byte[] inBytes, AccessibleBitmapBytewise inBitmap, out byte[] restBytes, int byteLayer)
        {
            //Create a AccessibleBitmapbitwise class from the incoming AccessibleBitmapbytewise class, for better access to individual bits
            AccessibleBitmapBitwise outputBitmap = new AccessibleBitmapBitwise(inBitmap);

            //Create a BitStreamFIFO class from the incoming bytes, to feed into the decompression algorithms
            BitStreamFIFO bitStream = new BitStreamFIFO(inBytes);

            //Loop trough all bit layers of current byte layer
            for (int i = byteLayer * 8; i < byteLayer * 8 + 8; i++)
            {
                //Read compression type as a 3-bit integer
                int compressionType = bitStream.ReadInt(3);

                //Decompress using the correct compression type
                switch (compressionType)
                {
                //Uncompressed
                case 0:
                    outputBitmap = UncompressedBitmapCompressorBitwise.Decompress(bitStream, outputBitmap, out bitStream, i);
                    break;

                //Bit channel compressed as 8-bit integers
                case 1:
                    outputBitmap = ByteArrayCompressorBitwise.Decompress(bitStream, outputBitmap, out bitStream, i);
                    break;

                //Run length encoding
                case 2:
                    outputBitmap = RunLengthEncodingCompressorBitwise.Decompress(bitStream, outputBitmap, out bitStream, i);
                    break;

                //Run length encoding vertical
                case 3:
                    outputBitmap = RunLengthEncodingCompressorVerticalBitwise.Decompress(bitStream, outputBitmap, out bitStream, i);
                    break;

                //To add a decompression type add a new case like the existing ones

                //Unknown compression type: error
                default:
                    throw new Exception("Unexisting compression type");
                }
            }
            //Remove the bytes used for this channel from the incoming byte array and pass the rest of them to the next channel
            restBytes = new byte[bitStream.Length / 8];
            Array.Copy(inBytes, inBytes.Length - (bitStream.Length / 8), restBytes, 0, restBytes.Length);

            //Return the modified bitmap as AccessibleBitmapbytewise so the rest of the channels can be added to complete it
            return(new AccessibleBitmapBytewise(outputBitmap.GetAccessibleBitmap()));
        }
Example #2
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);
        }