Skip to content

Instantly share code, notes, and snippets.

@hsytkm
Created January 20, 2024 04:00
Show Gist options
  • Save hsytkm/3a57b2731a06cede117b768f5bd21f3d to your computer and use it in GitHub Desktop.
Save hsytkm/3a57b2731a06cede117b768f5bd21f3d to your computer and use it in GitHub Desktop.
Create 16bit pgm/ppm images
using System.Text;
File.WriteAllText("_p2_16b.pgm", CreateP2_16b());
File.WriteAllText("_p3_16b_gray.ppm", CreateP3_Gray16b());
File.WriteAllText("_p3_16b_red.ppm", CreateP3_Red16b());
File.WriteAllText("_p3_16b_green_blue.ppm", CreateP3_GreenBlue16b());
File.WriteAllBytes("_p5_16b.pgm", CreateP5_16b());
File.WriteAllBytes("_p6_16b_red.pgm", CreateP6_Red16b());
File.WriteAllBytes("_p6_16b_green_blue.pgm", CreateP6_GreenBlue16b());
static string CreateP2_16b()
{
(int width, int height, int max) = (256, 256, 65535);
var sb = new StringBuilder($"""
P2
# Created by myself
{width} {height}
{max}
""");
const int newLineCount = 16;
var values = new List<ushort>();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x += newLineCount)
{
for (int n = x; n < x + newLineCount; n++)
{
var value = (ushort)Math.Min(0xffff, y * 256 + n);
values.Add(value);
}
sb.AppendLine(string.Join(' ', values));
values.Clear();
}
}
return sb.ToString();
}
static string CreateP3_Gray16b()
{
(int width, int height, int max) = (256, 256, 65535);
var sb = new StringBuilder($"""
P3
# Created by myself : Actual red image
{width} {height}
{max}
""");
const int newLineCount = 8;
var values = new List<ushort>();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x += newLineCount)
{
for (int n = x; n < x + newLineCount; n++)
{
var value = (ushort)Math.Min(0xffff, y * 256 + n);
values.Add(value); // 3ch RGB
values.Add(value);
values.Add(value);
}
sb.AppendLine(string.Join(' ', values));
values.Clear();
}
}
return sb.ToString();
}
static string CreateP3_Red16b()
{
(int width, int height, int max) = (256, 256, 65535);
var sb = new StringBuilder($"""
P3
# Created by myself : Actual gray image
{width} {height}
{max}
""");
const int newLineCount = 8;
var values = new List<ushort>();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x += newLineCount)
{
for (int n = x; n < x + newLineCount; n++)
{
var value = (ushort)Math.Min(0xffff, y * 256 + n);
values.Add(value); // 3ch RGB
values.Add(0);
values.Add(0);
}
sb.AppendLine(string.Join(' ', values));
values.Clear();
}
}
return sb.ToString();
}
static string CreateP3_GreenBlue16b()
{
(int width, int height, int max) = (256, 256, 65535);
var sb = new StringBuilder($"""
P3
# Created by myself : Actual green and blue image
{width} {height}
{max}
""");
const int newLineCount = 8;
var values = new List<ushort>();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x += newLineCount)
{
for (int n = x; n < x + newLineCount; n++)
{
var value = (ushort)Math.Min(0xffff, y * 256 + n);
values.Add(0); // 3ch RGB
values.Add((ushort)(0xffff - value));
values.Add(value);
}
sb.AppendLine(string.Join(' ', values));
values.Clear();
}
}
return sb.ToString();
}
static unsafe byte[] CreateP5_16b()
{
(int width, int height, int max) = (256, 256, 65535);
var headerBinary = Encoding.ASCII.GetBytes($"""
P5
# Created by myself
{width} {height}
{max}
""");
var headerSize = headerBinary.Length;
var pixelSize = width * height * sizeof(ushort);
var bs = new byte[headerSize + pixelSize];
for (int i = 0; i < headerSize; i++)
bs[i] = headerBinary[i];
fixed (byte* pixelHead = &bs[headerSize])
{
byte* ptr = pixelHead;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
var value = (ushort)Math.Min(0xffff, y * 256 + x);
// BigEndian
*(ptr++) = (byte)(value >> 8);
*(ptr++) = (byte)(value & 0x00ff);
}
}
}
return bs;
}
static unsafe byte[] CreateP6_Red16b()
{
(int width, int height, int max) = (256, 256, 65535);
var headerBinary = Encoding.ASCII.GetBytes($"""
P6
# Created by myself
{width} {height}
{max}
""");
var headerSize = headerBinary.Length;
var pixelSize = width * height * sizeof(ushort) * 3;
var bs = new byte[headerSize + pixelSize];
for (int i = 0; i < headerSize; i++)
bs[i] = headerBinary[i];
fixed (byte* pixelHead = &bs[headerSize])
{
byte* ptr = pixelHead;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
var value = (ushort)Math.Min(0xffff, y * 256 + x);
// BigEndian
*(ptr++) = (byte)(value >> 8);
*(ptr++) = (byte)(value & 0x00ff);
*(ptr++) = 0;
*(ptr++) = 0;
*(ptr++) = 0;
*(ptr++) = 0;
}
}
}
return bs;
}
static unsafe byte[] CreateP6_GreenBlue16b()
{
(int width, int height, int max) = (256, 256, 65535);
var headerBinary = Encoding.ASCII.GetBytes($"""
P6
# Created by myself
{width} {height}
{max}
""");
var headerSize = headerBinary.Length;
var pixelSize = width * height * sizeof(ushort) * 3;
var bs = new byte[headerSize + pixelSize];
for (int i = 0; i < headerSize; i++)
bs[i] = headerBinary[i];
fixed (byte* pixelHead = &bs[headerSize])
{
byte* ptr = pixelHead;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
var value1 = (ushort)Math.Min(0xffff, y * 256 + x);
var value2 = (ushort)0xffff - value1;
// BigEndian
*(ptr++) = 0;
*(ptr++) = 0;
*(ptr++) = (byte)(value2 >> 8);
*(ptr++) = (byte)(value2 & 0x00ff);
*(ptr++) = (byte)(value1 >> 8);
*(ptr++) = (byte)(value1 & 0x00ff);
}
}
}
return bs;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment