public TgaFileHeader( byte idLength, byte colorMapType, TgaImageType imageType, short cMapStart, short cMapLength, byte cMapDepth, short xOffset, short yOffset, short width, short height, byte pixelDepth, byte imageDescriptor) { this.IdLength = idLength; this.ColorMapType = colorMapType; this.ImageType = imageType; this.CMapStart = cMapStart; this.CMapLength = cMapLength; this.CMapDepth = cMapDepth; this.XOffset = xOffset; this.YOffset = yOffset; this.Width = width; this.Height = height; this.PixelDepth = pixelDepth; this.ImageDescriptor = imageDescriptor; }
/// <summary> /// Checks if this tga image type is run length encoded. /// </summary> /// <param name="imageType">The tga image type.</param> /// <returns>True, if this image type is run length encoded, otherwise false.</returns> public static bool IsRunLengthEncoded(this TgaImageType imageType) { if (imageType is TgaImageType.RleColorMapped || imageType is TgaImageType.RleBlackAndWhite || imageType is TgaImageType.RleTrueColor) { return(true); } return(false); }
/// <summary> /// Encodes the image to the specified stream from the <see cref="ImageFrame{TPixel}"/>. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="image">The <see cref="ImageFrame{TPixel}"/> to encode from.</param> /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param> public void Encode <TPixel>(Image <TPixel> image, Stream stream) where TPixel : struct, IPixel <TPixel> { Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); this.configuration = image.GetConfiguration(); ImageMetadata metadata = image.Metadata; TgaMetadata tgaMetadata = metadata.GetFormatMetadata(TgaFormat.Instance); this.bitsPerPixel = this.bitsPerPixel ?? tgaMetadata.BitsPerPixel; TgaImageType imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleTrueColor : TgaImageType.TrueColor; if (this.bitsPerPixel == TgaBitsPerPixel.Pixel8) { imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleBlackAndWhite : TgaImageType.BlackAndWhite; } // If compression is used, set bit 5 of the image descriptor to indicate an left top origin. byte imageDescriptor = (byte)(this.compression is TgaCompression.RunLength ? 32 : 0); var fileHeader = new TgaFileHeader( idLength: 0, colorMapType: 0, imageType: imageType, cMapStart: 0, cMapLength: 0, cMapDepth: 0, xOffset: 0, yOffset: this.compression is TgaCompression.RunLength ? (short)image.Height : (short)0, // When run length encoding is used, the origin should be top left instead of the default bottom left. width: (short)image.Width, height: (short)image.Height, pixelDepth: (byte)this.bitsPerPixel.Value, imageDescriptor: imageDescriptor); #if NETCOREAPP2_1 Span <byte> buffer = stackalloc byte[TgaFileHeader.Size]; #else byte[] buffer = new byte[TgaFileHeader.Size]; #endif fileHeader.WriteTo(buffer); stream.Write(buffer, 0, TgaFileHeader.Size); if (this.compression is TgaCompression.RunLength) { this.WriteRunLengthEndcodedImage(stream, image.Frames.RootFrame); } else { this.WriteImage(stream, image.Frames.RootFrame); } stream.Flush(); }
/// <summary> /// Checks, if the image type has valid value. /// </summary> /// <param name="imageType">The image type.</param> /// <returns>true, if its a valid tga image type.</returns> public static bool IsValid(this TgaImageType imageType) { switch (imageType) { case TgaImageType.NoImageData: case TgaImageType.ColorMapped: case TgaImageType.TrueColor: case TgaImageType.BlackAndWhite: case TgaImageType.RleColorMapped: case TgaImageType.RleTrueColor: case TgaImageType.RleBlackAndWhite: return(true); default: return(false); } }
/// <summary> /// Encodes the image to the specified stream from the <see cref="ImageFrame{TPixel}"/>. /// </summary> /// <typeparam name="TPixel">The pixel format.</typeparam> /// <param name="image">The <see cref="ImageFrame{TPixel}"/> to encode from.</param> /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param> public void Encode <TPixel>(Image <TPixel> image, Stream stream) where TPixel : unmanaged, IPixel <TPixel> { Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); this.configuration = image.GetConfiguration(); ImageMetadata metadata = image.Metadata; TgaMetadata tgaMetadata = metadata.GetTgaMetadata(); this.bitsPerPixel = this.bitsPerPixel ?? tgaMetadata.BitsPerPixel; TgaImageType imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleTrueColor : TgaImageType.TrueColor; if (this.bitsPerPixel == TgaBitsPerPixel.Pixel8) { imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleBlackAndWhite : TgaImageType.BlackAndWhite; } byte imageDescriptor = 0; if (this.compression is TgaCompression.RunLength) { // If compression is used, set bit 5 of the image descriptor to indicate a left top origin. imageDescriptor |= 0x20; } if (this.bitsPerPixel is TgaBitsPerPixel.Pixel32) { // Indicate, that 8 bit are used for the alpha channel. imageDescriptor |= 0x8; } if (this.bitsPerPixel is TgaBitsPerPixel.Pixel16) { // Indicate, that 1 bit is used for the alpha channel. imageDescriptor |= 0x1; } var fileHeader = new TgaFileHeader( idLength: 0, colorMapType: 0, imageType: imageType, cMapStart: 0, cMapLength: 0, cMapDepth: 0, xOffset: 0, yOffset: this.compression is TgaCompression.RunLength ? (short)image.Height : (short)0, // When run length encoding is used, the origin should be top left instead of the default bottom left. width: (short)image.Width, height: (short)image.Height, pixelDepth: (byte)this.bitsPerPixel.Value, imageDescriptor: imageDescriptor); Span <byte> buffer = stackalloc byte[TgaFileHeader.Size]; fileHeader.WriteTo(buffer); stream.Write(buffer, 0, TgaFileHeader.Size); if (this.compression is TgaCompression.RunLength) { this.WriteRunLengthEncodedImage(stream, image.Frames.RootFrame); } else { this.WriteImage(stream, image.Frames.RootFrame); } stream.Flush(); }