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))); }
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))); }
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)); }
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); }
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))); }
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))); }