public override void Dispose() { if (m_memory != null) { m_memory.Free(Buffer.Length); } else { m_parent.Dispose(); } }
public override void Dispose() { if (m_memory != null) { m_memory.Free(Image.Width * Image.Height); } else { m_parent.Dispose(); } }
public override void Dispose() { m_memory.Free(Palette.Size * 3); }
public static Image Decode(Stream stream, MemoryTracker memory, out Palette o_palette) { var reader = new BinaryReader(stream); // Read the header int imageIDLength = reader.ReadByte(); int colorMapType = reader.ReadByte(); int imageType = reader.ReadByte(); int colorMapStart = reader.ReadUInt16(); int colorMapLength = reader.ReadUInt16(); int colorMapBitsPerPixel = reader.ReadByte(); reader.ReadUInt16(); // xOffset reader.ReadUInt16(); // yOffset int width = reader.ReadUInt16(); int height = reader.ReadUInt16(); int bitsPerPixel = reader.ReadByte(); int imageDescriptor = reader.ReadByte(); if (bitsPerPixel != 8 || width == 0 || height == 0 || colorMapType != 1 || (colorMapStart + colorMapLength) == 0 || (colorMapStart + colorMapLength) > 256 || (colorMapBitsPerPixel != 24 && colorMapBitsPerPixel != 32) || (imageType != 1 && imageType != 9)) { throw new IOException("Unsupported TGA file"); } // Read the ID if (imageIDLength > 0) { reader.ReadBytes(imageIDLength); } // Read the color map int colorMapBytesPerPixel = colorMapBitsPerPixel / 8; var colorMap = reader.ReadBytes(colorMapLength * colorMapBytesPerPixel); var colors = new uint[colorMapStart + colorMapLength]; for (int i = 0; i < colors.Length; ++i) { if (i < colorMapStart) { colors[i] = 0x000000ff; } else { uint b = colorMap[(i - colorMapStart) * colorMapBytesPerPixel]; uint g = colorMap[(i - colorMapStart) * colorMapBytesPerPixel + 1]; uint r = colorMap[(i - colorMapStart) * colorMapBytesPerPixel + 2]; colors[i] = (r << 24) + (g << 16) + (b << 8) + 0xff; } } var palette = new Palette(colors); // Decode the image long size = width * height; if (palette != null) { size += 3 * palette.Size; } if (!memory.Alloc(size)) { throw new OutOfMemoryException(); } try { // Read the pixels byte[] buffer; bool rle = (imageType >= 8); if (rle) { // RLE buffer = new byte[width * height]; int pos = 0; while (pos < buffer.Length) { byte b = reader.ReadByte(); if (((int)b & 0x80) == 0x80) { // Run-length packet int count = ((int)b & 0x7f) + 1; byte value = reader.ReadByte(); int limit = Math.Min(pos + count, buffer.Length); while (pos < limit) { buffer[pos++] = value; } } else { // Non-run-length packet int count = ((int)b & 0x7f) + 1; int limit = Math.Min(pos + count, buffer.Length); while (pos < limit) { buffer[pos++] = reader.ReadByte(); } } } } else { // Non RLE buffer = reader.ReadBytes(width * height); } // Create the image bool flipY = (imageDescriptor & 0x20) == 0; var image = new Image(width, height); if (flipY) { for (int y = 0; y < height; ++y) { int flippedY = height - 1 - y; image.Write(buffer, y * width, width, 0, flippedY); } } else { image.Write(buffer, 0, width * height, 0, 0); } o_palette = palette; return(image); } catch { memory.Free(size); throw; } }