Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Unpac {
public static class Bitmap {
private static byte[] Header;
private readonly static byte[] Paleta;
static Bitmap() {
Header = new byte[0x436];
Header[0] = 0x42;
Header[1] = 0x4D;
Header[0xA] = 0x36;
Header[0xB] = 0x04;
Header[0xE] = 0x28;
Header[0x1A] = 1;
Header[0x1C] = 8;
Header[0x26] = 0x12;
Header[0x27] = 0x0B;
Header[0x2A] = 0x12;
Header[0x2B] = 0x0B;
// Grayscale palette
int dst_pos = 0x36;
int color;
for(color=0; color<0x100; color++) {
Header[dst_pos++] = (byte) (color << 2);
Header[dst_pos++] = (byte) (color << 2);
Header[dst_pos++] = (byte) (color << 2);
dst_pos++;
}
/*Paleta = new byte[] {
0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x05, 0x05, 0x05, 0x08, 0x08, 0x08, 0x0A, 0x0A, 0x0A, 0x0D,
0x0D, 0x0D, 0x10, 0x10, 0x10, 0x13, 0x13, 0x13, 0x16, 0x16, 0x16, 0x19, 0x19, 0x19, 0x1C, 0x1C,
0x1C, 0x1F, 0x1F, 0x1F, 0x22, 0x22, 0x22, 0x25, 0x25, 0x25, 0x27, 0x27, 0x27, 0x2A, 0x2A, 0x2A,
0x2D, 0x2D, 0x2D, 0x30, 0x30, 0x30, 0x33, 0x33, 0x33, 0x36, 0x36, 0x36, 0x39, 0x39, 0x39, 0x3C,
0x3C, 0x3C, 0x3F, 0x3F, 0x3F, 0x19, 0x3F, 0x19, 0x0F, 0x32, 0x0F, 0x08, 0x25, 0x08, 0x03, 0x19,
0x03, 0x39, 0x0C, 0x0C, 0x2E, 0x06, 0x06, 0x23, 0x01, 0x01, 0x18, 0x00, 0x00, 0x15, 0x3F, 0x3F,
0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x2C, 0x00, 0x00, 0x00, 0x17, 0x00, 0x3F, 0x38, 0x1F, 0x3C,
0x34, 0x1A, 0x39, 0x30, 0x16, 0x36, 0x2C, 0x12, 0x33, 0x28, 0x0E, 0x31, 0x24, 0x0B, 0x2E, 0x20,
0x08, 0x2B, 0x1D, 0x05, 0x28, 0x19, 0x03, 0x25, 0x16, 0x01, 0x23, 0x13, 0x00, 0x19, 0x27, 0x2E,
0x18, 0x18, 0x18, 0x1E, 0x1E, 0x1E, 0x0B, 0x0B, 0x0B, 0x2A, 0x00, 0x2A, 0x2A, 0x00, 0x2A, 0x2A,
0x00, 0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x00,
0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x00, 0x2A, 0x2A, 0x00, 0x2A,
0x1E, 0x20, 0x20, 0x12, 0x12, 0x12, 0x10, 0x10, 0x10, 0x0F, 0x0F, 0x0F, 0x0E, 0x0E, 0x0E, 0x0D,
0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0B, 0x0B, 0x0B, 0x00, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x08,
0x00, 0x00, 0x06, 0x00, 0x0B, 0x0C, 0x06, 0x0A, 0x0B, 0x06, 0x09, 0x0A, 0x06, 0x06, 0x06, 0x00,
0x09, 0x0A, 0x0A, 0x0D, 0x0D, 0x0D, 0x12, 0x12, 0x12, 0x19, 0x19, 0x19, 0x2B, 0x02, 0x00, 0x33,
0x1A, 0x06, 0x39, 0x2B, 0x0C, 0x3C, 0x33, 0x0F, 0x02, 0x11, 0x03, 0x07, 0x16, 0x06, 0x0F, 0x1B,
0x0D, 0x2F, 0x19, 0x12, 0x31, 0x31, 0x31, 0x35, 0x35, 0x35, 0x3A, 0x3A, 0x3A, 0x3F, 0x3F, 0x3F,
0x31, 0x3D, 0x3D, 0x2E, 0x3D, 0x3D, 0x2B, 0x3D, 0x3D, 0x28, 0x3D, 0x3D, 0x22, 0x3D, 0x3D, 0x1A,
0x3D, 0x3D, 0x17, 0x3B, 0x3D, 0x17, 0x39, 0x3D, 0x16, 0x38, 0x3D, 0x15, 0x37, 0x3D, 0x14, 0x36,
0x3D, 0x12, 0x34, 0x3D, 0x14, 0x28, 0x12, 0x00, 0x22, 0x0A, 0x00, 0x20, 0x09, 0x00, 0x1F, 0x08,
0x00, 0x1E, 0x07, 0x00, 0x1D, 0x06, 0x00, 0x1C, 0x05, 0x00, 0x1B, 0x04, 0x0E, 0x18, 0x2D, 0x00,
0x12, 0x22, 0x00, 0x11, 0x21, 0x00, 0x10, 0x20, 0x00, 0x0F, 0x1F, 0x00, 0x0E, 0x1E, 0x00, 0x0D,
0x1D, 0x00, 0x0C, 0x1C, 0x0F, 0x23, 0x0E, 0x01, 0x1A, 0x05, 0x00, 0x19, 0x04, 0x00, 0x18, 0x03,
0x00, 0x17, 0x02, 0x00, 0x16, 0x01, 0x00, 0x15, 0x00, 0x00, 0x14, 0x00, 0x13, 0x27, 0x15, 0x00,
0x1F, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x1A,
0x00, 0x00, 0x19, 0x00, 0x22, 0x22, 0x22, 0x18, 0x18, 0x17, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15,
0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x25, 0x13, 0x00,
0x1D, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x19, 0x00, 0x00, 0x18,
0x00, 0x00, 0x17, 0x00, 0x0A, 0x06, 0x00, 0x0E, 0x09, 0x00, 0x0F, 0x0C, 0x00, 0x13, 0x0F, 0x00,
0x19, 0x14, 0x00, 0x1A, 0x16, 0x00, 0x22, 0x1C, 0x12, 0x26, 0x22, 0x18, 0x2A, 0x2B, 0x1D, 0x20,
0x21, 0x0A, 0x1E, 0x1F, 0x08, 0x1D, 0x1E, 0x07, 0x1C, 0x1D, 0x06, 0x1B, 0x1C, 0x06, 0x1A, 0x1B,
0x06, 0x19, 0x1A, 0x06, 0x1B, 0x00, 0x00, 0x15, 0x00, 0x00, 0x20, 0x0A, 0x00, 0x1C, 0x08, 0x00,
0x04, 0x16, 0x09, 0x06, 0x1A, 0x0B, 0x09, 0x1C, 0x0D, 0x0A, 0x21, 0x2D, 0x06, 0x1C, 0x2E, 0x2B,
0x29, 0x35, 0x26, 0x25, 0x34, 0x2F, 0x2D, 0x36, 0x00, 0x12, 0x09, 0x38, 0x38, 0x38, 0x00, 0x0E,
0x08, 0x0A, 0x21, 0x22, 0x06, 0x1C, 0x1C, 0x2B, 0x29, 0x35, 0x26, 0x25, 0x34, 0x2F, 0x2D, 0x36,
0x00, 0x0E, 0x00, 0x04, 0x15, 0x04, 0x00, 0x18, 0x00, 0x08, 0x1D, 0x08, 0x1E, 0x20, 0x32, 0x2B,
0x29, 0x35, 0x3F, 0x15, 0x3F, 0x32, 0x00, 0x32, 0x08, 0x0E, 0x00, 0x0A, 0x11, 0x04, 0x11, 0x13,
0x00, 0x16, 0x18, 0x00, 0x23, 0x23, 0x1D, 0x2A, 0x29, 0x24, 0x3F, 0x15, 0x3F, 0x32, 0x00, 0x32,
0x03, 0x13, 0x07, 0x05, 0x17, 0x0A, 0x08, 0x1A, 0x0C, 0x0A, 0x1D, 0x0E, 0x1A, 0x2C, 0x3F, 0x14,
0x28, 0x3F, 0x00, 0x26, 0x3F, 0x3F, 0x15, 0x3F, 0x05, 0x0B, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x12,
0x00, 0x00, 0x15, 0x00, 0x1D, 0x23, 0x23, 0x1A, 0x1F, 0x1F, 0x16, 0x1A, 0x19, 0x3F, 0x15, 0x3F,
0x10, 0x14, 0x00, 0x12, 0x18, 0x00, 0x0F, 0x11, 0x00, 0x25, 0x25, 0x2A, 0x21, 0x21, 0x27, 0x21,
0x21, 0x26, 0x06, 0x0D, 0x00, 0x0B, 0x0F, 0x00, 0x30, 0x30, 0x36, 0x2A, 0x2C, 0x30, 0x27, 0x2A,
0x2D, 0x29, 0x29, 0x2E, 0x25, 0x25, 0x2B, 0x26, 0x26, 0x2B, 0x30, 0x32, 0x3C, 0x34, 0x35, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x0C, 0x20, 0x00, 0x20, 0x00, 0x0E, 0x0E, 0x0E, 0x28, 0x00, 0x00, 0x10,
0x14, 0x00, 0x0A, 0x0A, 0x0A, 0x29, 0x29, 0x29, 0x0F, 0x0F, 0x0F, 0x00, 0x22, 0x2E, 0x00, 0x2C,
0x00, 0x00, 0x39, 0x39, 0x39, 0x00, 0x00, 0x38, 0x28, 0x00, 0x3F, 0x34, 0x00, 0x3F, 0x3F, 0x3F
};
int src_pos = 0;
int dst_pos = 0x36;
int color;
for(color=0; color<0x100; color++) {
Header[dst_pos++] = (byte) (Paleta[src_pos++] << 2);
Header[dst_pos++] = (byte) (Paleta[src_pos++] << 2);
Header[dst_pos++] = (byte) (Paleta[src_pos++] << 2);
dst_pos++;
}*/
/*Paleta2 = new byte[] {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08,
0x09, 0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0E,
0x0E, 0x0E, 0x0F, 0x0E, 0x0E, 0x10, 0x0F, 0x0F, 0x11, 0x10, 0x10, 0x12, 0x11, 0x11, 0x13, 0x12,
0x12, 0x14, 0x13, 0x13, 0x15, 0x14, 0x14, 0x16, 0x15, 0x15, 0x17, 0x16, 0x16, 0x18, 0x17, 0x17,
0x19, 0x18, 0x18, 0x1A, 0x18, 0x18, 0x1B, 0x19, 0x19, 0x1C, 0x1A, 0x1A, 0x1D, 0x1B, 0x1B, 0x1E,
0x1C, 0x1C, 0x1F, 0x1D, 0x1D, 0x20, 0x1E, 0x1E, 0x21, 0x1F, 0x1F, 0x22, 0x20, 0x20, 0x23, 0x21,
0x21, 0x24, 0x22, 0x22, 0x25, 0x23, 0x23, 0x26, 0x24, 0x24, 0x27, 0x24, 0x24, 0x28, 0x25, 0x25,
0x29, 0x26, 0x26, 0x2A, 0x27, 0x27, 0x2B, 0x28, 0x28, 0x2C, 0x29, 0x29, 0x2D, 0x2A, 0x2A, 0x2E,
0x2B, 0x2B, 0x2F, 0x2C, 0x2C, 0x30, 0x2D, 0x2D, 0x31, 0x2E, 0x2E, 0x32, 0x2E, 0x2E, 0x33, 0x30,
0x30, 0x35, 0x30, 0x30, 0x36, 0x31, 0x31, 0x37, 0x32, 0x32, 0x38, 0x33, 0x33, 0x39, 0x34, 0x34,
0x3A, 0x35, 0x35, 0x3B, 0x36, 0x36, 0x3C, 0x37, 0x37, 0x3D, 0x38, 0x38, 0x3E, 0x39, 0x39, 0x3F
};
src_pos = 0;
dst_pos = 0x36;
for(color=0; color<64; color++) {
Header[dst_pos++] = (byte) (Paleta2[src_pos++] << 2);
Header[dst_pos++] = (byte) (Paleta2[src_pos++] << 2);
Header[dst_pos++] = (byte) (Paleta2[src_pos++] << 2);
dst_pos++;
}*/
}
public static bool Save(string filename, byte[] image_data, int width, int height) {
byte[] output_array;
int image_length;
int file_size;
int width_dword_align_padding;
int width_virtual;
bool fix_alignment;
int n;
int pos_src, pos_dst;
width_dword_align_padding = 4 - (width & 3);
width_virtual = width;
if(width_dword_align_padding != 4) width_virtual += width_dword_align_padding;
fix_alignment = width != width_virtual;
try {
image_length = width_virtual * height;
file_size = 0x436 + image_length;
output_array = new byte[file_size];
// Header
System.Buffer.BlockCopy(Header, 0, output_array, 0, 0x436);
// Header File size
System.Buffer.BlockCopy(BitConverter.GetBytes(file_size), 0, output_array, 2, 4);
// Header image width
System.Buffer.BlockCopy(BitConverter.GetBytes(width), 0, output_array, 0x12, 4);
// Header image height
System.Buffer.BlockCopy(BitConverter.GetBytes(0 - height), 0, output_array, 0x16, 4);
if(fix_alignment) {
pos_src = 0;
pos_dst = 0x436;
for(n=0; n<height; n++) {
System.Buffer.BlockCopy(image_data, pos_src, output_array, pos_dst, width);
pos_src += width;
pos_dst += width_virtual;
}
} else {
System.Buffer.BlockCopy(image_data, 0, output_array, 0x436, image_length);
}
System.IO.File.WriteAllBytes(filename, output_array);
} catch {
return false;
}
return true;
}
}
}