예제 #1
0
        private static void TestPngEncoderCore <TPixel>(
            TestImageProvider <TPixel> provider,
            PngColorType pngColorType,
            PngFilterMethod pngFilterMethod,
            PngBitDepth bitDepth,
            PngInterlaceMode interlaceMode,
            PngCompressionLevel compressionLevel = PngCompressionLevel.DefaultCompression,
            int paletteSize               = 255,
            bool appendPngColorType       = false,
            bool appendPngFilterMethod    = false,
            bool appendPixelType          = false,
            bool appendCompressionLevel   = false,
            bool appendPaletteSize        = false,
            bool appendPngBitDepth        = false,
            PngChunkFilter optimizeMethod = PngChunkFilter.None)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            using (Image <TPixel> image = provider.GetImage())
            {
                var encoder = new PngEncoder
                {
                    ColorType        = pngColorType,
                    FilterMethod     = pngFilterMethod,
                    CompressionLevel = compressionLevel,
                    BitDepth         = bitDepth,
                    Quantizer        = new WuQuantizer(new QuantizerOptions {
                        MaxColors = paletteSize
                    }),
                    InterlaceMethod = interlaceMode,
                    ChunkFilter     = optimizeMethod,
                };

                string pngColorTypeInfo     = appendPngColorType ? pngColorType.ToString() : string.Empty;
                string pngFilterMethodInfo  = appendPngFilterMethod ? pngFilterMethod.ToString() : string.Empty;
                string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : string.Empty;
                string paletteSizeInfo      = appendPaletteSize ? $"_PaletteSize-{paletteSize}" : string.Empty;
                string pngBitDepthInfo      = appendPngBitDepth ? bitDepth.ToString() : string.Empty;
                string pngInterlaceModeInfo = interlaceMode != PngInterlaceMode.None ? $"_{interlaceMode}" : string.Empty;

                string debugInfo = $"{pngColorTypeInfo}{pngFilterMethodInfo}{compressionLevelInfo}{paletteSizeInfo}{pngBitDepthInfo}{pngInterlaceModeInfo}";

                string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType);

                // Compare to the Magick reference decoder.
                IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);

                // We compare using both our decoder and the reference decoder as pixel transformation
                // occurs within the encoder itself leaving the input image unaffected.
                // This means we are benefiting from testing our decoder also.
                using (var imageSharpImage = Image.Load <TPixel>(actualOutputFile, new PngDecoder()))
                    using (var referenceImage = Image.Load <TPixel>(actualOutputFile, referenceDecoder))
                    {
                        ImageComparer.Exact.VerifySimilarity(referenceImage, imageSharpImage);
                    }
            }
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ZlibDeflateStream"/> class.
        /// </summary>
        /// <param name="memoryAllocator">The memory allocator to use for buffer allocations.</param>
        /// <param name="stream">The stream to compress.</param>
        /// <param name="level">The compression level.</param>
        public ZlibDeflateStream(MemoryAllocator memoryAllocator, Stream stream, PngCompressionLevel level)
        {
            int compressionLevel = (int)level;

            this.rawStream = stream;

            // Write the zlib header : http://tools.ietf.org/html/rfc1950
            // CMF(Compression Method and flags)
            // This byte is divided into a 4 - bit compression method and a
            // 4-bit information field depending on the compression method.
            // bits 0 to 3  CM Compression method
            // bits 4 to 7  CINFO Compression info
            //
            //   0   1
            // +---+---+
            // |CMF|FLG|
            // +---+---+
            const int Cmf = 0x78;
            int       flg = 218;

            // http://stackoverflow.com/a/2331025/277304
            if (compressionLevel >= 5 && compressionLevel <= 6)
            {
                flg = 156;
            }
            else if (compressionLevel >= 3 && compressionLevel <= 4)
            {
                flg = 94;
            }
            else if (compressionLevel <= 2)
            {
                flg = 1;
            }

            // Just in case
            flg -= ((Cmf * 256) + flg) % 31;

            if (flg < 0)
            {
                flg += 31;
            }

            this.rawStream.WriteByte(Cmf);
            this.rawStream.WriteByte((byte)flg);

            this.deflateStream = new DeflaterOutputStream(memoryAllocator, this.rawStream, compressionLevel);
        }
예제 #3
0
 public void WorksWithAllCompressionLevels <TPixel>(TestImageProvider <TPixel> provider, PngCompressionLevel compressionLevel)
     where TPixel : unmanaged, IPixel <TPixel>
 {
     foreach (PngInterlaceMode interlaceMode in InterlaceMode)
     {
         TestPngEncoderCore(
             provider,
             PngColorType.RgbWithAlpha,
             PngFilterMethod.Adaptive,
             PngBitDepth.Bit8,
             interlaceMode,
             compressionLevel,
             appendCompressionLevel: true);
     }
 }