Beispiel #1
0
        private byte[] EncodeColorInternal(Bitmap image, IProgressContext progress = null)
        {
            var paddedSize = _paddedSize?.Invoke(image.Size) ?? Size.Empty;
            var size       = paddedSize.IsEmpty ? image.Size : paddedSize;

            // If we have quantization enabled
            IEnumerable <Color> colors;

            if (_quantizer != null)
            {
                var scopedProgresses = progress?.SplitIntoEvenScopes(2);

                var(indices, palette) = QuantizeImage(image, paddedSize, scopedProgresses?[0]);

                // Recompose indices to colors
                var setMaxProgress = scopedProgresses?[1]?.SetMaxValue(image.Width * image.Height);
                colors = indices.ToColors(palette).AttachProgress(setMaxProgress, "Encode indices");
            }
            else
            {
                // Decompose image to colors
                var setMaxProgress = progress?.SetMaxValue(image.Width * image.Height);
                colors = image.ToColors(paddedSize, _swizzle?.Invoke(size)).AttachProgress(setMaxProgress, "Encode colors");
            }

            // Save color data
            return(_colorEncoding().Save(colors, new EncodingSaveContext(image.Size, _taskCount)));
        }
Beispiel #2
0
        private Bitmap DecodeColorInternal(byte[] data, Size imageSize, IProgressContext progress)
        {
            var paddedSize = _paddedSize?.Invoke(imageSize) ?? Size.Empty;
            var finalSize  = paddedSize.IsEmpty ? imageSize : paddedSize;

            var colorEncoding = _colorEncoding();

            // Load colors
            var valueCount       = data.Length * 8 / colorEncoding.BitsPerValue;
            var valueCountBySize = finalSize.Width * finalSize.Height / colorEncoding.ColorsPerValue;

            // HINT: If the data portion does not fit with the actual image size, it will cause progress irregularities.
            //       If the given data is shorter than what is needed  for the full image, we throw.
            //       Otherwise enough data is given and the image can be fully decoded, even if excess data is not used.
            if (valueCount < valueCountBySize)
            {
                throw new InvalidOperationException("Given data is too short.");
            }

            var setMaxProgress = progress?.SetMaxValue(valueCountBySize * colorEncoding.ColorsPerValue);
            var colors         = colorEncoding
                                 .Load(data, new EncodingLoadContext(imageSize, _taskCount))
                                 .AttachProgress(setMaxProgress, "Decode colors");

            // Create image with unpadded dimensions
            return(colors.ToBitmap(imageSize, paddedSize, _swizzle?.Invoke(finalSize)));
        }
Beispiel #3
0
        private Bitmap DecodeColorInternal(byte[] data, Size imageSize, IProgressContext progress)
        {
            // Prepare information and instances
            var paddedSize  = GetPaddedSize(imageSize);
            var swizzle     = GetPixelRemapper(_colorEncoding, paddedSize);
            var finalSize   = GetFinalSize(paddedSize, swizzle);
            var colorShader = _shadeColorsFunc?.Invoke();

            // Load colors
            var colorCount       = data.Length * 8 / _colorEncoding.BitsPerValue * _colorEncoding.ColorsPerValue;
            var colorCountBySize = finalSize.Width * finalSize.Height;

            // HINT: If the data portion does not fit with the actual image size, it will cause progress irregularities.
            //       If the given data is shorter than what is needed for the full image, we throw.
            //       Otherwise enough data is given and the image can be fully decoded, even if excess data is not used.
            if (colorCount < colorCountBySize)
            {
                throw new InvalidOperationException("Given data is too short.");
            }

            var setMaxProgress = progress?.SetMaxValue(colorCountBySize * _colorEncoding.ColorsPerValue);
            var colors         = _colorEncoding
                                 .Load(data, new EncodingLoadContext(finalSize, _taskCount))
                                 .AttachProgress(setMaxProgress, "Decode colors");

            // Apply color shader
            if (colorShader != null)
            {
                colors = colors.Select(colorShader.Read);
            }

            // Create image with unpadded dimensions
            return(colors.ToBitmap(imageSize, paddedSize, swizzle, _anchor));
        }
Beispiel #4
0
        public (IEnumerable <int>, IList <Color>) Process(IEnumerable <Color> colors, Size imageSize,
                                                          IProgressContext progress = null)
        {
            var colorList = colors.ToList();

            var colorCache = GetColorCache(colorList, _taskCount);

            var setMaxProgress = progress?.SetMaxValue(colorList.Count);

            var colorDitherer = _dithererFunc?.Invoke(imageSize, _taskCount);
            var indices       = colorDitherer == null?
                                colorList.ToIndices(colorCache) :
                                    colorDitherer.Process(colorList, colorCache);

            return(indices.AttachProgress(setMaxProgress, "Encode indices"), colorCache.Palette);
        }
Beispiel #5
0
        private Bitmap DecodeColorInternal(byte[] data, Size imageSize, IProgressContext progress)
        {
            var paddedSize = _paddedSize?.Invoke(imageSize) ?? Size.Empty;

            var colorEncoding = _colorEncoding(imageSize);

            // Load colors
            // TODO: Size is currently only used for block compression with native libs,
            // TODO: Those libs should retrieve the actual size of the image, not the padded dimensions
            var valueCount     = data.Length * 8 / colorEncoding.BitsPerValue;
            var setMaxProgress = progress?.SetMaxValue(valueCount * colorEncoding.ColorsPerValue);
            var colors         = colorEncoding
                                 .Load(data, _taskCount)
                                 .AttachProgress(setMaxProgress, "Decode colors");

            // Create image with unpadded dimensions
            return(colors.ToBitmap(imageSize, paddedSize, _swizzle?.Invoke(paddedSize.IsEmpty ? imageSize : paddedSize)));
        }
Beispiel #6
0
        private byte[] EncodeColorInternal(Bitmap image, IProgressContext progress = null)
        {
            // Prepare information and instances
            var paddedSize  = GetPaddedSize(image.Size);
            var swizzle     = GetPixelRemapper(_colorEncoding, paddedSize);
            var finalSize   = GetFinalSize(paddedSize, swizzle);
            var colorShader = _shadeColorsFunc?.Invoke();

            // If we have quantization enabled
            IEnumerable <Color> colors;

            if (_quantizer != null)
            {
                var scopedProgresses = progress?.SplitIntoEvenScopes(2);

                // HINT: Color shader is applied by QuantizeImage
                var(indices, palette) = QuantizeImage(image, paddedSize, swizzle, scopedProgresses?[0]);

                // Recompose indices to colors
                var setMaxProgress = scopedProgresses?[1]?.SetMaxValue(finalSize.Width * finalSize.Height);
                colors = indices.ToColors(palette).AttachProgress(setMaxProgress, "Encode indices");
            }
            else
            {
                // Decompose image to colors
                var setMaxProgress = progress?.SetMaxValue(finalSize.Width * finalSize.Height);
                colors = image.ToColors(paddedSize, swizzle, _anchor).AttachProgress(setMaxProgress, "Encode colors");

                // Apply color shader
                if (colorShader != null)
                {
                    colors = colors.Select(colorShader.Write);
                }
            }

            // Save color data
            return(_colorEncoding.Save(colors, new EncodingSaveContext(finalSize, _taskCount)));
        }