Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * QuickBASIC BSAVE Graphics Plugin for Paint.NET
- * (C) Copywrite Graham Downey 2016
- */
- using System;
- using System.Collections.Generic;
- using System.Text;
- using PaintDotNet;
- using PaintDotNet.Data;
- using System.IO;
- using System.Reflection;
- using System.Drawing;
- using System.Windows.Forms;
- using System.Drawing.Imaging;
- namespace QuickBASIC_BSAVE_Graphics
- {
- public class MyFileType : FileType
- {
- public MyFileType()
- : base("QuickBASIC BSAVE Graphics",
- FileTypeFlags.SupportsLoading | FileTypeFlags.SupportsSaving,
- new String[] { ".VGA", ".BSV" })
- {
- }
- // VGA Color Palette
- public Color[] Palette = new Color[256];
- protected override Document OnLoad(Stream input)
- {
- try
- {
- int Magic = input.ReadByte();
- if (Magic != 0xFD)
- {
- MessageBox.Show("ERROR: Not a QuickBASIC BSAVE graphics file!");
- Bitmap blank = new Bitmap(16, 16);
- return Document.FromImage(blank);
- }
- input.Seek(5, 0); // Skip Segment/Offset data
- int LowByte = input.ReadByte();
- int DataSize = input.ReadByte();
- DataSize = (DataSize << 8) | LowByte;
- LowByte = input.ReadByte();
- int GFXWidth = input.ReadByte();
- GFXWidth = (GFXWidth << 8) | LowByte;
- GFXWidth = (GFXWidth >> 3);
- LowByte = input.ReadByte();
- int GFXHeight = input.ReadByte();
- GFXHeight = (GFXHeight << 8) | LowByte;
- if (GFXWidth*GFXHeight != DataSize-4)
- {
- MessageBox.Show("ERROR: Not a Screen 13 graphics file!");
- Bitmap Blank = new Bitmap(16, 16);
- return Document.FromImage(Blank);
- }
- // Read bitmap bytes into byte buffer
- byte[] ByteBuffer = new byte[DataSize];
- int DataRead = 0;
- while (DataSize-4 != 0)
- {
- DataRead = input.Read(ByteBuffer, DataRead, DataSize);
- DataSize -= DataRead;
- }
- // Load VGA color palette
- int R, B, G, C;
- Stream PalStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("QuickBASIC_BSAVE_Graphics.SCR13.PAL");
- for (C = 0; C < 256; C++)
- {
- R = PalStream.ReadByte();
- B = PalStream.ReadByte();
- G = PalStream.ReadByte();
- Palette[C] = Color.FromArgb(R, G, B);
- }
- PalStream.Dispose();
- // Convert byte array into .NET bitmap
- Bitmap GFX = new Bitmap(GFXWidth, GFXHeight);
- for (int X = 0; X < GFXWidth; X++)
- {
- for (int Y = 0; Y < GFXHeight; Y++)
- {
- GFX.SetPixel(X, Y, Palette[Convert.ToInt32(ByteBuffer[X+(Y*GFXWidth)])]);
- }
- }
- return Document.FromImage(GFX);
- }
- catch
- {
- MessageBox.Show("ERROR: Unknown fatal error loading file!");
- Bitmap b = new Bitmap(16, 16);
- return Document.FromImage(b);
- }
- }
- protected override void OnSave(Document input, Stream output, SaveConfigToken token,
- Surface scratchSurface, ProgressEventHandler callback)
- {
- //Render bitmap
- RenderArgs ra = new RenderArgs(new Surface(input.Size));
- input.Render(ra, false);
- // Load VGA Color palette
- int R, B, G, C;
- Stream PalStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("QuickBASIC_BSAVE_Graphics.SCR13.PAL");
- for (C = 0; C < 256; C++)
- {
- R = PalStream.ReadByte();
- B = PalStream.ReadByte();
- G = PalStream.ReadByte();
- Palette[C] = Color.FromArgb(R, G, B);
- }
- PalStream.Dispose();
- // Get dimensions from bitmap
- int GFXWidth = ra.Bitmap.Width;
- int GFXHeight = ra.Bitmap.Height;
- int DataSize = GFXWidth * GFXHeight + 4;
- // Generate file header
- byte[] header = new byte[7];
- header[0] = 0xFD; //Magic
- header[1] = 0x9C; header[2] = 0x00; //Segment
- header[3] = 0x00; header[4] = 0x00; //Offset
- header[5] = Convert.ToByte(DataSize & 0xFF); //Low byte of DataSize
- header[6] = Convert.ToByte(DataSize >> 8); //High byte of DataSize
- byte[] GFX = new byte[DataSize];
- // Generate bitmap data
- for (int X = 0; X < GFXWidth; X++)
- {
- for (int Y = 0; Y < GFXHeight; Y++)
- {
- GFX[X+(Y*GFXWidth)+4] = Convert.ToByte(NearestColor(ra.Bitmap.GetPixel(X, Y)));
- }
- }
- GFXWidth = GFXWidth << 3; //In Screen 13 QB stores Width*8
- GFX[0] = Convert.ToByte(GFXWidth & 0xFF); //Lowbyte of GFXWidth
- GFX[1] = Convert.ToByte(GFXWidth >> 8); //Highbyte of GFXWidth
- GFX[2] = Convert.ToByte(GFXHeight & 0xFF); //Lowbyte of GFXHeight
- GFX[3] = Convert.ToByte(GFXHeight >> 8); //Highbyte of GFXHeight
- output.Write(header, 0, 7); //Write header to file
- output.Write(GFX, 0, DataSize); //Write bitmap to file
- }
- private int NearestColor(Color Pixel)
- {
- int diffR; int diffB; int diffG;
- int smallestDiffValue = 0x7FFFFFFF;
- int SmallestDiff = 0x00;
- int diff = 0x00;
- for (int C = 0; C < 256; C++)
- {
- diffR = Pixel.R - Palette[C].R;
- diffB = Pixel.B - Palette[C].B;
- diffG = Pixel.G - Palette[C].G;
- diff = (diffR*diffR) + (diffB*diffB) + (diffG*diffG);
- if (diff == 0) { return C; } // Quit early if match found
- if (diff < smallestDiffValue) // Otherwise compare to smallest color found
- { SmallestDiff = C; smallestDiffValue = diff; }
- }
- return SmallestDiff;
- }
- }
- public class MyFileTypeFactory : IFileTypeFactory
- {
- public FileType[] GetFileTypeInstances()
- {
- return new FileType[] { new MyFileType() };
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement