コード例 #1
0
        /// <summary>
        /// Reverses the filtering process done on the decompressed
        /// datastream to get the unfiltered datastream.
        /// </summary>
        /// <param name="filter_type">The type of filtering process done on the section of data.</param>
        private byte[] unfilter_scanline(Filter_Types filter_type, byte[] filtered_scanline_bytes, byte[] previous_scanline_bytes)
        {
            byte[] result = null;

            switch (filter_type)
            {
            case (Filter_Types.SUB):
                result = unfilter_sub_scanline(filtered_scanline_bytes);
                break;

            case (Filter_Types.UP):
                result = unfilter_up_scanline(filtered_scanline_bytes, previous_scanline_bytes);
                break;

            case (Filter_Types.AVERAGE):
                result = unfilter_avg_scanline(filtered_scanline_bytes, previous_scanline_bytes);
                break;

            case (Filter_Types.PAETH):
                result = unfilter_paeth_scanline(filtered_scanline_bytes, previous_scanline_bytes);
                break;

            default:
                result = new byte[filtered_scanline_bytes.Length - 1];
                for (int i = 1; i < filtered_scanline_bytes.Length; i++)
                {
                    result[i - 1] = filtered_scanline_bytes[i];
                }
                break;
            }

            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Reverses the filtering of the bytes passed in.
        /// Assumes that the bytes are a one-dimensional array of all of
        /// the bytes of data. This means that one scanline comes after
        /// another, and this method uses the stored height/width fields
        /// of the PNG file decoded to determine when a new scanline is
        /// reached. Also assumes that the PNG file is valid.
        /// </summary>
        /// <param name="decompressed_datastream">The decompressed datastream to be unfiltered.</param>
        /// <returns>An array of bytes that contains the unfiltered, decompressed datastream's bytes.</returns>
        private byte[] unfilter_datastream(byte[] decompressed_datastream)
        {
            if (!is_valid_png ||
                decompressed_datastream == null)
            {
                return(null);
            }

            List <byte> unfiltered_bytes = new List <byte>();

            // process the first scanline
            byte[] previous_scanline = new byte[width_p * pixel_width_p + 1];
            byte[] current_scanline  = new byte[width_p * pixel_width_p + 1];
            int    byte_index        = 0;


            Filter_Types filter_type = (Filter_Types)decompressed_datastream[byte_index++];

            current_scanline[0] = decompressed_datastream_p[0];

            // specially handle the first scanline (no previous scanline) and add results to
            // the unfiltered bytes list
            for (; byte_index < width_p * pixel_width_p + 1;)
            {
                current_scanline[byte_index] = decompressed_datastream[byte_index];
                ++byte_index;
            }
            byte_index        = 0;
            previous_scanline = unfilter_scanline(filter_type, current_scanline, previous_scanline);
            foreach (byte scanline_byte in previous_scanline)
            {
                unfiltered_bytes.Add(scanline_byte);
            }

            // unfilter the other scanlines, and add them to the list
            for (int i = 1; i < height_p; i++)
            {
                int scanline_length = (int)width_p * pixel_width + 1;
                int first_bit_index = (scanline_length) * i;

                current_scanline[0] = decompressed_datastream[first_bit_index + byte_index++];
                filter_type         = (Filter_Types)current_scanline[0];

                for (; byte_index < scanline_length;)
                {
                    current_scanline[byte_index] = decompressed_datastream[first_bit_index + byte_index];
                    ++byte_index;
                }
                previous_scanline = unfilter_scanline(filter_type, current_scanline, previous_scanline);
                foreach (byte scanline_byte in previous_scanline)
                {
                    unfiltered_bytes.Add(scanline_byte);
                }
                byte_index = 0;
            }

            return(unfiltered_bytes.ToArray());
        }