Beispiel #1
0
        internal static bool IsFastPremultiplied(this IBitmapData bitmapData)
        {
            PixelFormat pixelFormat = bitmapData.PixelFormat;

            return(pixelFormat == PixelFormat.Format32bppPArgb ||
                   pixelFormat.IsPremultiplied() && (!(bitmapData is NativeBitmapDataBase) || ColorExtensions.Max16BppValue == UInt16.MaxValue));
        }
Beispiel #2
0
        private static void AdjustQuantizerAndDitherer(IBitmapData target, ref IQuantizer quantizer, ref IDitherer ditherer)
        {
            if (quantizer != null || ditherer == null)
            {
                return;
            }

            if (target.PixelFormat.CanBeDithered())
            {
                quantizer = PredefinedColorsQuantizer.FromBitmapData(target);
            }
            else
            {
                ditherer = null;
            }
        }
Beispiel #3
0
        private static bool HasAlpha(this IBitmapData bitmapData)
        {
            PixelFormat pixelFormat = bitmapData.PixelFormat;

            return(pixelFormat.HasAlpha() || pixelFormat.IsIndexed() && bitmapData.Palette?.HasAlpha == true);
        }
Beispiel #4
0
 internal static Size GetSize(this IBitmapData bitmapData) => bitmapData == null ? default : new Size(bitmapData.Width, bitmapData.Height);
Beispiel #5
0
        internal static bool HasMultiLevelAlpha(this IBitmapData bitmapData)
        {
            PixelFormat pixelFormat = bitmapData.PixelFormat;

            return(pixelFormat.HasMultiLevelAlpha() || pixelFormat.IsIndexed() && bitmapData.Palette?.HasMultiLevelAlpha == true);
        }
Beispiel #6
0
        internal ClippedBitmapData(IBitmapData source, Rectangle clippingRegion)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            region = clippingRegion;

            // source is already clipped: unwrapping to prevent tiered nesting (not calling Unwrap because other types should not be extracted here)
            if (source is ClippedBitmapData parent)
            {
                BitmapData = parent.BitmapData;
                region.Offset(parent.region.Location);
                region.Intersect(parent.region);
            }
            else
            {
                BitmapData = source;
                region.Intersect(new Rectangle(Point.Empty, source.GetSize()));
            }

            if (region.IsEmpty)
            {
                throw new ArgumentOutOfRangeException(nameof(clippingRegion), PublicResources.ArgumentOutOfRange);
            }

            bitmapDataType = BitmapData switch
            {
                IBitmapDataInternal _ => BitmapDataType.Internal,
                IReadWriteBitmapData _ => BitmapDataType.ReadWrite,
                IReadableBitmapData _ => BitmapDataType.Readable,
                IWritableBitmapData _ => BitmapDataType.Writable,
                                    _ => BitmapDataType.None
            };

            PixelFormat    = BitmapData.PixelFormat;
            BackColor      = BitmapData.BackColor;
            AlphaThreshold = BitmapData.AlphaThreshold;
            Palette        = BitmapData.Palette;
            int bpp = PixelFormat.ToBitsPerPixel();

            int maxRowSize = (region.Width * bpp) >> 3;
            RowSize = region.Left > 0
                      // Any clipping from the left disables raw access because ReadRaw/WriteRaw offset depends on size of T,
                      // which will fail for any T whose size is not the same as the actual pixel size
                ? 0
                      // Even one byte padding is disabled to protect the right edge of a region by default
                : Math.Min(source.RowSize, maxRowSize);

            if (bpp >= 8 || RowSize < maxRowSize)
            {
                return;
            }

            // 1/4bpp: Adjust RowSize if needed
            // right edge: if not at byte boundary but that is the right edge of the original image, then we allow including padding
            if (PixelFormat.IsAtByteBoundary(region.Width) && region.Right == BitmapData.Width)
            {
                RowSize++;
            }
        }
Beispiel #7
0
 public void Initialize(int requestedColors, IBitmapData source)
 {
     maxColors = requestedColors;
     root      = new ColorBucket(source.Width * source.Height);
 }
 public void Initialize(int requestedColors, IBitmapData source) => maxColors = requestedColors;
 public BitmapShot(IBitmapData bitmapData) => BitmapData = bitmapData;
Beispiel #10
0
            internal DitheringSessionRaster(IQuantizingSession quantizer, ErrorDiffusionDitherer ditherer, IBitmapData source)
            {
                this.quantizer = quantizer;
                this.ditherer  = ditherer;
                ImageWidth     = source.Width;
                imageHeight    = source.Height;
                byBrightness   = ditherer.byBrightness ?? quantizer.Palette?.IsGrayscale ?? false;

                // Initializing a circular buffer for the diffused errors.
                // This helps to minimize used memory because it needs only a few lines to be stored.
                // Another solution could be to store resulting colors instead of just the errors but then the color
                // entries would be clipped not just in the end but in every iteration, and small errors would be lost
                // that could stack up otherwise.
                // See also the ErrorDiffusionDitherer constructor for more comments on why using floats.
                errorsBuffer = new CircularList <(float, float, float)[]>(ditherer.matrixHeight);