// This draws the picture to the given pixel color data // Throws exception on failure public void DrawToPixelData(Stream stream, PixelColor *target, int targetwidth, int targetheight, int x, int y) { int width, height, ox, oy; // Read pixel data PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height, out ox, out oy); if (pixeldata != null) { // Go for all source pixels // We don't care about the original image offset, so reuse ox/oy for (ox = 0; ox < width; ox++) { for (oy = 0; oy < height; oy++) { // Copy this pixel? if (pixeldata.Pointer[oy * width + ox].a > 0.5f) { // Calculate target pixel and copy when within bounds int tx = x + ox; int ty = y + oy; if ((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight)) { target[ty * targetwidth + tx] = pixeldata.Pointer[oy * width + ox]; } } } } } }
// This creates a Bitmap from the given data // Returns null on failure public Bitmap ReadAsBitmap(Stream stream) { int width, height; Bitmap bmp; // Read pixel data PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height); if (pixeldata != null) { try { // Create bitmap and lock pixels bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); PixelColor *targetdata = (PixelColor *)bitmapdata.Scan0.ToPointer(); // Copy the pixels General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor))); // Done bmp.UnlockBits(bitmapdata); } catch (Exception e) { // Unable to make bitmap General.ErrorLogger.Add(ErrorType.Error, "Unable to make Doom flat data. " + e.GetType().Name + ": " + e.Message); return(null); } } else { // Failed loading picture bmp = null; } // Return result return(bmp); }
// This creates pixel color data from the given data // Returns null on failure private PixelColorBlock ReadAsPixelData(Stream stream, out int width, out int height, out int offsetx, out int offsety) { BinaryReader reader = new BinaryReader(stream); PixelColorBlock pixeldata = null; int y, read_y, count, p; int[] columns; int dataoffset; // Initialize width = 0; height = 0; offsetx = 0; offsety = 0; dataoffset = (int)stream.Position; // Need at least 4 bytes if ((stream.Length - stream.Position) < 4) { return(null); } #if !DEBUG try { #endif // Read size and offset width = reader.ReadInt16(); height = reader.ReadInt16(); offsetx = reader.ReadInt16(); offsety = reader.ReadInt16(); // Valid width and height? if ((width <= 0) || (height <= 0)) { return(null); } // Read the column addresses columns = new int[width]; for (int x = 0; x < width; x++) { columns[x] = reader.ReadInt32(); } // Allocate memory pixeldata = new PixelColorBlock(width, height); pixeldata.Clear(); // Go for all columns for (int x = 0; x < width; x++) { // Seek to column start stream.Seek(dataoffset + columns[x], SeekOrigin.Begin); // Read first post start y = reader.ReadByte(); read_y = y; // Continue while not end of column reached while (read_y < 255) { // Read number of pixels in post count = reader.ReadByte(); // Skip unused pixel stream.Seek(1, SeekOrigin.Current); // Draw post for (int yo = 0; yo < count; yo++) { // Read pixel color index p = reader.ReadByte(); // Draw pixel pixeldata.Pointer[(y + yo) * width + x] = palette[p]; } // Skip unused pixel stream.Seek(1, SeekOrigin.Current); // Read next post start read_y = reader.ReadByte(); if (read_y < y) { y += read_y; } else { y = read_y; } } } // Return pointer return(pixeldata); #if !DEBUG } catch (Exception) { // Return nothing return(null); } #endif }
// This creates pixel color data from the given data // Returns null on failure private PixelColorBlock ReadAsPixelData(Stream stream, out int width, out int height) { // Check if the flat is square float sqrlength = (float)Math.Sqrt(stream.Length); if (sqrlength == (float)Math.Truncate(sqrlength)) { // Calculate image size width = (int)sqrlength; height = (int)sqrlength; } // Check if the data is more than 4096 else if (stream.Length > 4096) { // Image will be 64x64 width = 64; height = 64; } else { // Invalid width = 0; height = 0; return(null); } #if !DEBUG try { #endif // Valid width and height? if ((width <= 0) || (height <= 0)) { return(null); } // Allocate memory PixelColorBlock pixeldata = new PixelColorBlock(width, height); pixeldata.Clear(); // Read flat bytes from stream byte[] bytes = new byte[width * height]; stream.Read(bytes, 0, width * height); // Convert bytes with palette for (uint i = 0; i < width * height; i++) { pixeldata.Pointer[i] = palette[bytes[i]]; } // Return pointer return(pixeldata); #if !DEBUG } catch (Exception) { // Return nothing return(null); } #endif }
// This creates pixel color data from the given data // Returns null on failure private unsafe PixelColorBlock ReadAsPixelData(Stream stream, out int width, out int height) { // Image will be 128x128 width = 128; height = 128; #if !DEBUG try { #endif // Allocate memory PixelColorBlock pixeldata = new PixelColorBlock(width, height); pixeldata.Clear(); // Read flat bytes from stream byte[] bytes = new byte[width * height]; stream.Read(bytes, 0, width * height); // Draw blocks using the palette // We want to draw 8x8 blocks for each color // 16 wide and 16 high uint i = 0; for (int by = 0; by < 16; by++) { for (int bx = 0; bx < 16; bx++) { PixelColor bc = palette[bytes[i++]]; PixelColor bc1 = General.Colors.CreateBrightVariant(palette[bytes[i++]]); PixelColor bc2 = General.Colors.CreateDarkVariant(palette[bytes[i++]]); for (int py = 0; py < 8; py++) { for (int px = 0; px < 8; px++) { int p = ((by * 8) + py) * width + (bx * 8) + px; // We make the borders slightly brighter and darker if ((py == 0) || (px == 0)) { pixeldata.Pointer[p] = bc1; } else if ((py == 7) || (px == 7)) { pixeldata.Pointer[p] = bc2; } else { pixeldata.Pointer[p] = bc; } } } } } // Return pointer return(pixeldata); #if !DEBUG } catch (Exception) { // Return nothing return(null); } #endif }