public void HalfVector4_PackFromBgra32_ToBgra32() { // arrange var halVector = default(HalfVector4); var actual = default(Bgra32); var expected = new Bgra32(64, 128, 191, 255); // act halVector.PackFromBgra32(expected); halVector.ToBgra32(ref actual); // assert Assert.Equal(expected, actual); }
public void Argb32_PackFromBgra32_ToBgra32() { // arrange var argb = default(Argb32); var actual = default(Bgra32); var expected = new Bgra32(0x1a, 0, 0x80, 0); // act argb.PackFromBgra32(expected); argb.ToBgra32(ref actual); // assert Assert.Equal(expected, actual); }
public void Rgba32_FromBgra32_ToRgba32() { // arrange var rgba = default(Rgba32); var actual = default(Bgra32); var expected = new Bgra32(0x1a, 0, 0x80, 0); // act rgba.FromBgra32(expected); actual.FromRgba32(rgba); // assert Assert.Equal(expected, actual); }
public void Short4_PackFromBgra32_ToRgba32() { // arrange var short4 = default(Short4); var actual = default(Bgra32); var expected = new Bgra32(20, 38, 0, 255); // act short4.PackFromBgra32(expected); short4.ToBgra32(ref actual); // assert Assert.Equal(expected, actual); }
public void Rgba1010102_PackFromBgra32_ToBgra32() { // arrange var rgba = default(Rgba1010102); var expected = new Bgra32(25, 0, 128, 0); var actual = default(Bgra32); // act rgba.PackFromBgra32(expected); rgba.ToBgra32(ref actual); // assert Assert.Equal(expected, actual); }
static public void ConvertVTFandAlphaToPNG(string texturepath) { // Load our VTF image into memory var vtffilestream = File.Open(texturepath, FileMode.Open); var vtf = new VtfFile(vtffilestream); // Iterate through all mipmaps and find the biggest one (the only one we care about) int largestdatasize = 0; VtfImage biggestVTFimage = null; foreach (var mipmap in vtf.Images) { if (mipmap.Data.Length > largestdatasize) { largestdatasize = mipmap.Data.Length; biggestVTFimage = mipmap; } } // Grab the raw 32-bit BGRA8888 data from the image var image = biggestVTFimage.GetBgra32Data(); // Put the raw data into lists, one being a list of the basetexture pixels, and one being the alpha image channel var basepixellist = new List <Bgra32>(); var alphapixellist = new List <Gray8>(); for (int i = 0; i < image.Length; i += 4) { var thisbasepixel = new Bgra32(image[i + 2], image[i + 1], image[i]); var thisalphapixel = new Gray8(image[i + 3]); basepixellist.Add(thisbasepixel); alphapixellist.Add(thisalphapixel); } // Build the images out of our list var combinedbaseimage = Image.LoadPixelData <Bgra32>(basepixellist.ToArray(), biggestVTFimage.Width, biggestVTFimage.Height); var combinedalphaimage = Image.LoadPixelData <Gray8>(alphapixellist.ToArray(), biggestVTFimage.Width, biggestVTFimage.Height); // TODO: Fix the save paths based on file name using (var bifs = new FileStream("basetexture.png", FileMode.Create)) { combinedbaseimage.SaveAsPng(bifs); } using (var aifs = new FileStream("basetexture_alpha.png", FileMode.Create)) { combinedalphaimage.SaveAsPng(aifs); } }
public void Alpha8_PackFromScaledVector4_ToBgra32() { // arrange Bgra32 actual = default; Alpha8 alpha = default; var expected = new Bgra32(0, 0, 0, 128); Vector4 scaled = new Alpha8(.5F).ToScaledVector4(); // act alpha.PackFromScaledVector4(scaled); alpha.ToBgra32(ref actual); // assert Assert.Equal(expected, actual); }
public void Short4_FromBgra32_ToRgba32() { // arrange var short4 = default(Short4); var actual = default(Bgra32); var expected = new Bgra32(20, 38, 0, 255); // act short4.FromBgra32(expected); Rgba32 temp = default; short4.ToRgba32(ref temp); actual.FromRgba32(temp); // assert Assert.Equal(expected, actual); }
/// <summary> /// Initializes a new instance of the <see cref="QuantizedImage"/> class. /// </summary> /// <param name="width">The image width.</param> /// <param name="height">The image height.</param> /// <param name="palette">The color palette.</param> /// <param name="pixels">The quantized pixels.</param> public QuantizedImage(int width, int height, Bgra32[] palette, byte[] pixels) { Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); Guard.NotNull(palette, nameof(palette)); Guard.NotNull(pixels, nameof(pixels)); if (pixels.Length != width * height) { throw new ArgumentException( $"Pixel array size must be {nameof(width)} * {nameof(height)}", nameof(pixels)); } this.Width = width; this.Height = height; this.Palette = palette; this.Pixels = pixels; }
public static Image <Bgra32> ConvertBgra32(BinaryReader br, int width, int height) { Image <Bgra32> img = new Image <Bgra32>(width, height); for (int y = 0; y < height; ++y) { var row = img.GetPixelRowSpan(y); for (int x = 0; x < width; ++x) { byte b = br.ReadByte(); byte g = br.ReadByte(); byte r = br.ReadByte(); byte a = br.ReadByte(); row[x] = new Bgra32(r, g, b, a); } } return(img); }
/// <summary> /// Generate normal texture from height map. /// Note : heightMap should be in projected coordinates (see ReprojectToCartesian()) /// </summary> /// <param name="heightMap">heightMap in projected coordinates</param> /// <param name="outputDirectory"></param> /// <returns></returns> public TextureInfo GenerateNormalMap(HeightMap heightMap, string outputDirectory, string fileName = "normalmap.png") { List <Vector3> normals = _meshService.ComputeNormals(heightMap).ToList(); #if NETSTANDARD using (Image <Bgra32> outputImage = new Image <Bgra32>(heightMap.Width, heightMap.Height)) { for (int j = 0; j < heightMap.Height; j++) { for (int i = 0; i < heightMap.Width; i++) { int index = i + (j * heightMap.Width); Vector3 norm = normals[index]; Bgra32 color = FromVec3NormalToColor(norm); outputImage[i, j] = color; } } outputImage.Save(System.IO.Path.Combine(outputDirectory, fileName)); } #elif NETFULL using (var dbm = new DirectBitmap(heightMap.Width, heightMap.Height)) { for (int j = 0; j < heightMap.Height; j++) { for (int i = 0; i < heightMap.Width; i++) { int index = i + (j * heightMap.Width); Vector3 norm = normals[index]; Color color = FromVec3NormalToColor(norm); dbm.SetPixel(i, j, color); } } dbm.Bitmap.Save(Path.Combine(outputDirectory, fileName), ImageFormat.Png); } #endif TextureInfo normal = new TextureInfo(System.IO.Path.Combine(outputDirectory, fileName), TextureImageFormat.image_jpeg, heightMap.Width, heightMap.Height); return(normal); }
public void WrapSystemDrawingBitmap_WhenObserved() { if (ShouldSkipBitmapTest) { return; } using (var bmp = new Bitmap(51, 23)) { using (var memoryManager = new BitmapMemoryManager(bmp)) { Memory <Bgra32> memory = memoryManager.Memory; Bgra32 bg = Color.Red; Bgra32 fg = Color.Green; using (var image = Image.WrapMemory(memory, bmp.Width, bmp.Height)) { Assert.Equal(memory, image.GetRootFramePixelBuffer().DangerousGetSingleMemory()); image.GetPixelMemoryGroup().Fill(bg); image.ProcessPixelRows(accessor => { for (var i = 10; i < 20; i++) { accessor.GetRowSpan(i).Slice(10, 10).Fill(fg); } }); } Assert.False(memoryManager.IsDisposed); } if (!Directory.Exists(TestEnvironment.ActualOutputDirectoryFullPath)) { Directory.CreateDirectory(TestEnvironment.ActualOutputDirectoryFullPath); } string fn = System.IO.Path.Combine( TestEnvironment.ActualOutputDirectoryFullPath, $"{nameof(this.WrapSystemDrawingBitmap_WhenObserved)}.bmp"); bmp.Save(fn, ImageFormat.Bmp); } }
private static void ReadBitmap32(ByteReader reader, ParseContext context, int height, int width, IcoFrame source) { for (var y = height - 1; y >= 0; y--) { for (var x = 0; x < width; x++) { var colorValue = new Bgra32 { PackedValue = reader.NextUint32() }; source.CookedData[x, y] = colorValue.ToRgba32(); } } source.Encoding.PixelFormat = BmpUtil.IsAnyAlphaChannel(source.CookedData) ? BitmapEncoding.Pixel_argb32 : BitmapEncoding.Pixel_0rgb32; ReadBitmapMask(reader, context, height, width, source); }
public Image ToImage() { Image image = Image.Clone(); foreach (Wire wire in Wires) { byte alpha = wire.IsActive ? (byte)255 : (byte)127; foreach (Point point in wire.Points) { int x = point.X; int y = point.Y; Bgra32 color = highImage[x, y]; image[x, y] = new Bgra32(color.R, color.G, color.B, alpha); } } return(image); }
public void CloneAs_ToBgra32(TestImageProvider <Rgba32> provider) { using (Image <Rgba32> image = provider.GetImage()) using (Image <Bgra32> clone = image.CloneAs <Bgra32>()) { for (int y = 0; y < image.Height; y++) { Span <Rgba32> row = image.GetPixelRowSpan(y); Span <Bgra32> rowClone = clone.GetPixelRowSpan(y); for (int x = 0; x < image.Width; x++) { Rgba32 expected = row[x]; Bgra32 actual = rowClone[x]; Assert.Equal(expected.R, actual.R); Assert.Equal(expected.G, actual.G); Assert.Equal(expected.B, actual.B); Assert.Equal(expected.A, actual.A); } } } }
public void CloneAs_ToBgra32(TestImageProvider <Rgba32> provider) { using (Image <Rgba32> image = provider.GetImage()) using (Image <Bgra32> clone = image.CloneAs <Bgra32>()) { for (int y = 0; y < image.Height; y++) { Span <Rgba32> row = image.GetPixelRowSpan(y); Span <Bgra32> rowClone = clone.GetPixelRowSpan(y); for (int x = 0; x < image.Width; x++) { Rgba32 rgba = row[x]; Bgra32 bgra = rowClone[x]; Assert.Equal(rgba.R, bgra.R); Assert.Equal(rgba.G, bgra.G); Assert.Equal(rgba.B, bgra.B); Assert.Equal(rgba.A, bgra.A); } } } }
public void WrapSystemDrawingBitmap_WhenOwned() { using (var bmp = new Bitmap(51, 23)) { var memoryManager = new BitmapMemoryManager(bmp); Bgra32 bg = NamedColors <Bgra32> .Red; Bgra32 fg = NamedColors <Bgra32> .Green; using (var image = Image.WrapMemory(memoryManager, bmp.Width, bmp.Height)) { Assert.Equal(memoryManager.Memory, image.GetPixelMemory()); image.Mutate(c => c.Fill(bg).Fill(fg, new RectangularPolygon(10, 10, 10, 10))); } Assert.True(memoryManager.IsDisposed); string fn = System.IO.Path.Combine( TestEnvironment.ActualOutputDirectoryFullPath, $"{nameof(this.WrapSystemDrawingBitmap_WhenOwned)}.bmp"); bmp.Save(fn, ImageFormat.Bmp); } }
private Image <Bgra32> DecodeFormat0(IBinaryStream reader) { var data = reader.ReadBytesExact(_alignedWidth * _alignedHeight * 4); var pixels = new Bgra32[Width * Height]; foreach (var i in Range(_alignedWidth * _alignedHeight)) { var x = GetX(i, _alignedWidth, 4); var y = GetY(i, _alignedWidth, 4); if (x >= Width || y >= Height) { continue; } var src = i * 4; pixels[x + y * Width] = new Bgra32( b: data[src + 3], g: data[src + 2], r: data[src + 1], a: data[src] ); } return(Image.LoadPixelData(pixels, Width, Height)); }
public void ToVector4() { var rgb = new Bgra32(1, 2, 3, 4); Assert.Equal(Vec(1, 2, 3, 4), rgb.ToVector4()); }
public Color(Bgra32 pixel) { this.data = new Rgba64(pixel); this.boxedHighPrecisionPixel = null; }
public void ToBgra32(ref Bgra32 dest) { throw new NotImplementedException(); }
/// <summary> /// Increment the pixel count and add to the color information /// </summary> /// <param name="pixel"> /// The pixel to add. /// </param> public void Increment(Bgra32 pixel) { this.pixelCount++; this.red += pixel.R; this.green += pixel.G; this.blue += pixel.B; }
/// <summary> /// Reads the 32 bit color palette from the stream, checking the alpha component of each pixel. /// This is a special case only used for 32bpp WinBMPv3 files, which could be in either BGR0 or BGRA format. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> to assign the palette to.</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 ReadRgb32Slow <TPixel>(Buffer2D <TPixel> pixels, int width, int height, bool inverted) where TPixel : struct, IPixel <TPixel> { int padding = CalculatePadding(width, 4); using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 4, padding)) using (IMemoryOwner <Bgra32> bgraRow = this.memoryAllocator.Allocate <Bgra32>(width)) { Span <Bgra32> bgraRowSpan = bgraRow.GetSpan(); long currentPosition = this.stream.Position; bool hasAlpha = false; // Loop though the rows checking each pixel. We start by assuming it's // an BGR0 image. If we hit a non-zero alpha value, then we know it's // actually a BGRA image, and change tactics accordingly. for (int y = 0; y < height; y++) { this.stream.Read(row); PixelOperations <Bgra32> .Instance.FromBgra32Bytes( this.configuration, row.GetSpan(), bgraRowSpan, width); // Check each pixel in the row to see if it has an alpha value. for (int x = 0; x < width; x++) { Bgra32 bgra = bgraRowSpan[x]; if (bgra.A > 0) { hasAlpha = true; break; } } if (hasAlpha) { break; } } // Reset our stream for a second pass. this.stream.Position = currentPosition; // Process the pixels in bulk taking the raw alpha component value. if (hasAlpha) { for (int y = 0; y < height; y++) { this.stream.Read(row); int newY = Invert(y, height, inverted); Span <TPixel> pixelSpan = pixels.GetRowSpan(newY); PixelOperations <TPixel> .Instance.FromBgra32Bytes( this.configuration, row.GetSpan(), pixelSpan, width); } return; } // Slow path. We need to set each alpha component value to fully opaque. for (int y = 0; y < height; y++) { this.stream.Read(row); PixelOperations <Bgra32> .Instance.FromBgra32Bytes( this.configuration, row.GetSpan(), bgraRowSpan, width); int newY = Invert(y, height, inverted); Span <TPixel> pixelSpan = pixels.GetRowSpan(newY); for (int x = 0; x < width; x++) { Bgra32 bgra = bgraRowSpan[x]; bgra.A = byte.MaxValue; ref TPixel pixel = ref pixelSpan[x]; pixel.FromBgra32(bgra); } } }
public void PackFromBgra32(Bgra32 source) { PackedValue = FromLinearRgb(source.R, source.G, source.B); }
/// <summary> /// Get the palette index for the passed color /// </summary> /// <param name="pixel"> /// The <see cref="Bgra32"/> containing the pixel data. /// </param> /// <returns> /// The index of the given structure. /// </returns> public int GetPaletteIndex(Bgra32 pixel) { return this.root.GetPaletteIndex(pixel, 0); }
public void PackFromBgra32(Bgra32 source) { this = FromRgba(source.R, source.G, source.B, source.A); }
/// <summary> /// Add a color into the tree /// </summary> /// <param name="pixel"> /// The color /// </param> /// <param name="colorBits"> /// The number of significant color bits /// </param> /// <param name="level"> /// The level in the tree /// </param> /// <param name="octree"> /// The tree to which this node belongs /// </param> public void AddColor(Bgra32 pixel, int colorBits, int level, Octree octree) { // Update the color information if this is a leaf if (this.leaf) { this.Increment(pixel); // Setup the previous node octree.TrackPrevious(this); } else { // Go to the next level down in the tree int shift = 7 - level; int index = ((pixel.R & Mask[level]) >> (shift - 2)) | ((pixel.G & Mask[level]) >> (shift - 1)) | ((pixel.B & Mask[level]) >> shift); OctreeNode child = this.children[index]; if (child == null) { // Create a new child node and store it in the array child = new OctreeNode(level + 1, colorBits, octree); this.children[index] = child; } // Add the color to the child node child.AddColor(pixel, colorBits, level + 1, octree); } }
/// <summary> /// Return the palette index for the passed color /// </summary> /// <param name="pixel"> /// The <see cref="Bgra32"/> representing the pixel. /// </param> /// <param name="level"> /// The level. /// </param> /// <returns> /// The <see cref="int"/> representing the index of the pixel in the palette. /// </returns> public int GetPaletteIndex(Bgra32 pixel, int level) { int index = this.paletteIndex; if (!this.leaf) { int shift = 7 - level; int pixelIndex = ((pixel.R & Mask[level]) >> (shift - 2)) | ((pixel.G & Mask[level]) >> (shift - 1)) | ((pixel.B & Mask[level]) >> shift); if (this.children[pixelIndex] != null) { index = this.children[pixelIndex].GetPaletteIndex(pixel, level + 1); } else { throw new Exception("Didn't expect this!"); } } return index; }
public static CircuitBoard FromImage(Image image) { if (image == null) { throw new ArgumentNullException(nameof(image)); } int width = image.Width; int height = image.Height; var highImage = new Image(width, height); var lowImage = new Image(width, height); var board = new CircuitBoard(image, highImage, lowImage); if (width == 0 || height == 0) { return(board); } var map = board.WireMap; if (image.IsWire(0, 0)) { var t = new Wire(false, new Point(0, 0)); map[0, 0] = t; board.Wires.Add(t); } for (int x = 1; x < width; x++) { if (image.IsWire(x, 0)) { var point = new Point(x, 0); Wire wire = map[x - 1, 0]; if (wire != null) { map[x, 0] = wire; wire.Points.Add(point); } else { var t = new Wire(false, point); map[x, 0] = t; board.Wires.Add(t); } } } for (int y = 1; y < height; y++) { if (image.IsWire(0, y)) { var point = new Point(0, y); Wire wire = map[0, y - 1]; if (wire != null) { map[0, y] = wire; wire.Points.Add(point); } else { var t = new Wire(false, point); map[0, y] = t; board.Wires.Add(t); } } for (int x = 1; x < width; x++) { if (image.IsWire(x, y)) { var point = new Point(x, y); Wire wire = map[x, y - 1]; if (wire != null) { map[x, y] = wire; wire.Points.Add(point); var wire2 = map[x - 1, y]; if (wire2 != null && wire != wire2) { foreach (Point p in wire2.Points) { map[p.X, p.Y] = wire; wire.Points.Add(p); } board.Wires.Remove(wire2); } } else { wire = map[x - 1, y]; if (wire != null) { map[x, y] = wire; wire.Points.Add(point); } else { var t = new Wire(false, point); map[x, y] = t; board.Wires.Add(t); } } } } } for (int y = 1; y < height - 1; y++) { for (int x = 1; x < width - 1; x++) { Wire t1 = map[x - 1, y - 1]; Wire t2 = map[x, y - 1]; Wire t3 = map[x + 1, y - 1]; Wire t4 = map[x - 1, y]; Wire t5 = map[x, y]; Wire t6 = map[x + 1, y]; Wire t7 = map[x - 1, y + 1]; Wire t8 = map[x, y + 1]; Wire t9 = map[x + 1, y + 1]; if (t1 == null && t2 != null && t3 == null && t4 != null && t5 == null && t6 != null && t7 == null && t8 != null && t9 == null) { if (t2 != t8) { board.MergeWires(t2, t8); } if (t4 != t6) { board.MergeWires(t4, t6); } } } } for (int y = 1; y < height - 1; y++) { for (int x = 1; x < width - 1; x++) { Wire t1 = map[x - 1, y - 1]; Wire t2 = map[x, y - 1]; Wire t3 = map[x + 1, y - 1]; Wire t4 = map[x - 1, y]; Wire t5 = map[x, y]; Wire t6 = map[x + 1, y]; Wire t7 = map[x - 1, y + 1]; Wire t8 = map[x, y + 1]; Wire t9 = map[x + 1, y + 1]; if (t1 == null && t2 != null && t3 == null && t4 == null && t5 == null && t6 == null && t7 != null && t8 != null && t9 != null) { t2.SourceWires.Add(t8); } else if (t1 == null && t2 == null && t3 != null && t4 != null && t5 == null && t6 != null && t7 == null && t8 == null && t9 != null) { t4.SourceWires.Add(t6); } else if (t1 != null && t2 != null && t3 != null && t4 == null && t5 == null && t6 == null && t7 == null && t8 != null && t9 == null) { t8.SourceWires.Add(t2); } else if (t1 != null && t2 == null && t3 == null && t4 != null && t5 == null && t6 != null && t7 != null && t8 == null && t9 == null) { t6.SourceWires.Add(t4); } //if (t1 == null && t2 != null && t3 == null && t4 != null && t5 == null && t6 != null && t7 != null && t8 != null && t9 != null) //{ // t2.SourceWires.Add(t8); //} //else if (t1 == null && t2 != null && t3 != null && t4 != null && t5 == null && t6 != null && t7 == null && t8 != null && t9 != null) //{ // t4.SourceWires.Add(t6); //} //else if (t1 != null && t2 != null && t3 != null && t4 != null && t5 == null && t6 != null && t7 == null && t8 != null && t9 == null) //{ // t8.SourceWires.Add(t2); //} //else if (t1 != null && t2 != null && t3 == null && t4 != null && t5 == null && t6 != null && t7 != null && t8 != null && t9 == null) //{ // t6.SourceWires.Add(t4); //} } } foreach (Wire wire in board.Wires) { int active = 0; foreach (Point point in wire.Points) { int x = point.X; int y = point.Y; Bgra32 color = image[x, y]; byte r = color.R; byte g = color.G; byte b = color.B; byte a = color.A; highImage[x, y] = new Bgra32(r, g, b); lowImage[x, y] = new Bgra32((byte)(r / 2), (byte)(g / 2), (byte)(b / 2)); if (a >= 128) { active++; } else { active--; } } wire.IsActive = active > 0; Image i = wire.IsActive ? board.highImage : board.lowImage; foreach (Point point in wire.Points) { int x = point.X; int y = point.Y; image[x, y] = i[x, y]; } } return(board); }
private static Bgra32 Lerp(Bgra32 c1, Bgra32 c2, double t1, double t2) => new(
public void FromBgra32(Bgra32 source) { }
/// <inheritdoc /> public void FromBgra32(Bgra32 source) { throw new NotImplementedException(); }
public void PackFromBgra32(Bgra32 source) => Pack(source.R, source.G, source.B);
/// <summary> /// Add a given color value to the Octree /// </summary> /// <param name="pixel"> /// The <see cref="Bgra32"/>containing color information to add. /// </param> public void AddColor(Bgra32 pixel) { // Check if this request is for the same color as the last if (this.previousColor == pixel.Bgra) { // If so, check if I have a previous node setup. This will only occur if the first color in the image // happens to be black, with an alpha component of zero. if (this.previousNode == null) { this.previousColor = pixel.Bgra; this.root.AddColor(pixel, this.maxColorBits, 0, this); } else { // Just update the previous node this.previousNode.Increment(pixel); } } else { this.previousColor = pixel.Bgra; this.root.AddColor(pixel, this.maxColorBits, 0, this); } }
/// <summary> /// Override this to process the pixel in the first pass of the algorithm /// </summary> /// <param name="pixel"> /// The pixel to quantize /// </param> /// <remarks> /// This function need only be overridden if your quantize algorithm needs two passes, /// such as an Octree quantizer. /// </remarks> protected virtual void InitialQuantizePixel(Bgra32 pixel) { }
private static void ReadIndexedBitmap(ByteReader reader, ParseContext context, uint bitDepth, uint colorTableSize, int height, int width, IcoFrame source) { var anyReservedChannel = false; var anyIndexOutOfBounds = false; if (colorTableSize == 0) { colorTableSize = 1u << (int)bitDepth; } source.Encoding.PaletteSize = colorTableSize; if (colorTableSize > 1u << (int)bitDepth) { throw new InvalidIcoFileException(IcoErrorCode.InvalidBitapInfoHeader_biClrUsed, $"BITMAPINFOHEADER.biClrUsed is greater than 2^biBitCount (biClrUsed == {colorTableSize}, biBitCount = {bitDepth}).", context); } else if (colorTableSize < 1u << (int)bitDepth) { context.Reporter.WarnLine(IcoErrorCode.UndersizedColorTable, $"This bitmap uses a color table that is smaller than the bit depth ({colorTableSize} < 2^{bitDepth})", context.DisplayedPath, context.ImageDirectoryIndex.Value); } var colorTable = new Rgba32[colorTableSize]; for (var i = 0; i < colorTableSize; i++) { var c = new Bgra32 { PackedValue = reader.NextUint32() }; if (c.A != 0) { anyReservedChannel = true; } c.A = 255; colorTable[i] = c.ToRgba32(); } var padding = reader.SeekOffset % 4; for (var y = height - 1; y >= 0; y--) { var bits = new BitReader(reader); for (var x = 0; x < width; x++) { var colorIndex = bits.NextBit(bitDepth); if (colorIndex >= colorTableSize) { anyIndexOutOfBounds = true; source.CookedData[x, y] = Rgba32.Black; } else { source.CookedData[x, y] = colorTable[colorIndex]; } } while ((reader.SeekOffset % 4) != padding) { reader.SeekOffset += 1; } } switch (bitDepth) { case 1: source.Encoding.PixelFormat = BitmapEncoding.Pixel_indexed1; break; case 2: source.Encoding.PixelFormat = BitmapEncoding.Pixel_indexed2; break; case 4: source.Encoding.PixelFormat = BitmapEncoding.Pixel_indexed4; break; case 8: source.Encoding.PixelFormat = BitmapEncoding.Pixel_indexed8; break; } ReadBitmapMask(reader, context, height, width, source); if (anyReservedChannel) { context.Reporter.WarnLine(IcoErrorCode.NonzeroAlpha, $"Reserved Alpha channel used in color table.", context.DisplayedPath, context.ImageDirectoryIndex.Value); } if (anyIndexOutOfBounds) { context.Reporter.WarnLine(IcoErrorCode.IndexedColorOutOfBounds, $"Bitmap uses color at illegal index; pixel filled with Black color.", context.DisplayedPath, context.ImageDirectoryIndex.Value); } }
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <summary> /// Override this to process the pixel in the second pass of the algorithm /// </summary> /// <param name="pixel"> /// The pixel to quantize /// </param> /// <returns> /// The quantized value /// </returns> protected abstract byte QuantizePixel(Bgra32 pixel);