/// <summary> /// Looks up color values and builds the image from de-compressed RLE8 data. /// Compresssed RLE8 stream is uncompressed by <see cref="UncompressRle8(int, Span{byte})"/> /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> to assign the palette to.</param> /// <param name="colors">The <see cref="T:byte[]"/> containing the colors.</param> /// <param name="width">The width of the bitmap.</param> /// <param name="height">The height of the bitmap.</param> /// <param name="inverted">Whether the bitmap is inverted.</param> private void ReadRle8 <TPixel>(PixelAccessor <TPixel> pixels, byte[] colors, int width, int height, bool inverted) where TPixel : struct, IPixel <TPixel> { var color = default(TPixel); var rgba = new Rgba32(0, 0, 0, 255); using (var buffer = Buffer2D <byte> .CreateClean(width, height)) { this.UncompressRle8(width, buffer); for (int y = 0; y < height; y++) { int newY = Invert(y, height, inverted); Span <byte> bufferRow = buffer.GetRowSpan(y); Span <TPixel> pixelRow = pixels.GetRowSpan(newY); for (int x = 0; x < width; x++) { rgba.Bgr = Unsafe.As <byte, Bgr24>(ref colors[bufferRow[x] * 4]); color.PackFromRgba32(rgba); pixelRow[x] = color; } } } }
/// <summary> /// Initializes <see cref="SpectralBlocks"/> /// </summary> /// <param name="decoder">The <see cref="OrigJpegDecoderCore"/> instance</param> public void InitializeDerivedData(OrigJpegDecoderCore decoder) { // For 4-component images (either CMYK or YCbCrK), we only support two // hv vectors: [0x11 0x11 0x11 0x11] and [0x22 0x11 0x11 0x22]. // Theoretically, 4-component JPEG images could mix and match hv values // but in practice, those two combinations are the only ones in use, // and it simplifies the applyBlack code below if we can assume that: // - for CMYK, the C and K channels have full samples, and if the M // and Y channels subsample, they subsample both horizontally and // vertically. // - for YCbCrK, the Y and K channels have full samples. this.SizeInBlocks = decoder.ImageSizeInMCU.MultiplyBy(this.SamplingFactors); if (this.Index == 0 || this.Index == 3) { this.SubSamplingDivisors = new Size(1, 1); } else { OrigComponent c0 = decoder.Components[0]; this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); } this.SpectralBlocks = Buffer2D <Block8x8> .CreateClean(this.SizeInBlocks); }
/// <summary> /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class. /// </summary> /// <param name="width">The width of the image in pixels.</param> /// <param name="height">The height of the image in pixels.</param> /// <param name="metaData">The meta data.</param> internal ImageFrame(int width, int height, ImageFrameMetaData metaData) { Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); Guard.NotNull(metaData, nameof(metaData)); this.pixelBuffer = Buffer2D <TPixel> .CreateClean(width, height); this.MetaData = metaData; }
#pragma warning restore SA1401 /// <summary> /// Initializes a new instance of the <see cref="YCbCrImage" /> class. /// </summary> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="ratio">The ratio.</param> public YCbCrImage(int width, int height, YCbCrSubsampleRatio ratio) { Size cSize = CalculateChrominanceSize(width, height, ratio); this.Ratio = ratio; this.YStride = width; this.CStride = cSize.Width; this.YChannel = Buffer2D <byte> .CreateClean(width, height); this.CbChannel = Buffer2D <byte> .CreateClean(cSize.Width, cSize.Height); this.CrChannel = Buffer2D <byte> .CreateClean(cSize.Width, cSize.Height); }
/// <summary> /// Initializes a new instance of the <see cref="PixelAccessor{TPixel}"/> class. /// </summary> /// <param name="width">The width of the image represented by the pixel buffer.</param> /// <param name="height">The height of the image represented by the pixel buffer.</param> public PixelAccessor(int width, int height) : this(width, height, Buffer2D <TPixel> .CreateClean(width, height), true) { }
/// <summary> /// Initializes a new instance of the <see cref="WeightsBuffer"/> class. /// </summary> /// <param name="sourceSize">The size of the source window</param> /// <param name="destinationSize">The size of the destination window</param> public WeightsBuffer(int sourceSize, int destinationSize) { this.dataBuffer = Buffer2D <float> .CreateClean(sourceSize, destinationSize); this.Weights = new WeightsWindow[destinationSize]; }