Skip to content

Instantly share code, notes, and snippets.

@corruptmem
Created April 4, 2012 00:36
Show Gist options
  • Save corruptmem/2296713 to your computer and use it in GitHub Desktop.
Save corruptmem/2296713 to your computer and use it in GitHub Desktop.
Pixmap thingy
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Detect
{
enum ParserState
{
Header,
Width,
Depth,
Height,
Data
}
class PpmLoader
{
public int? Width { get; private set; }
public int? Height { get; private set; }
public byte[][][] Buffer { get; private set; }
public void Save(string filename)
{
using (var f = File.OpenWrite(filename))
{
var header = Encoding.ASCII.GetBytes(string.Format("P6\n{0}\n{1}\n255\n", Width, Height));
f.Write(header, 0, header.Length);
for (var y = 0; y < Height; y++)
{
for (var x = 0; x < Width; x++)
{
for (var d = 0; d < 3; d++)
{
f.WriteByte(Buffer[y][x][d]);
}
}
}
}
}
public void Load(string filename)
{
Width = null;
Height = null;
Buffer = null;
using (var f = File.OpenRead(filename))
{
var initial = new[]
{
ParserState.Header,
ParserState.Depth,
ParserState.Width,
ParserState.Height
};
var whitespace = new[] { '\t', ' ', '\n', '\r' };
byte[] token = null;
int tokenSize = 0;
int nextByte;
int x = 0;
int y = 0;
int p = 0;
Action reset = () =>
{
token = new byte[256];
tokenSize = 0;
};
reset();
var state = ParserState.Header;
while ((nextByte = f.ReadByte()) != -1)
{
if (state == ParserState.Data)
{
if (Buffer == null)
{
throw new InvalidOperationException("Buffer was null");
}
Buffer[y][x][p] = (byte)nextByte;
p++;
if (p > 2)
{
p = 0;
x++;
}
if (x >= Width)
{
x = 0;
y++;
}
if (y >= Height)
{
break;
}
}
else
{
if (initial.Contains(state) && tokenSize == 0 && whitespace.Contains((char)nextByte))
{
continue;
}
if (whitespace.Contains((char)nextByte) && tokenSize > 0 && state != ParserState.Data)
{
switch (state)
{
case ParserState.Header:
if (Encoding.ASCII.GetString(token, 0, tokenSize) != "P6")
{
throw new InvalidOperationException("Not P6");
}
state = ParserState.Width;
reset();
break;
case ParserState.Height:
Height = int.Parse(Encoding.ASCII.GetString(token, 0, tokenSize));
state = ParserState.Depth;
reset();
break;
case ParserState.Width:
Width = int.Parse(Encoding.ASCII.GetString(token, 0, tokenSize));
state = ParserState.Height;
reset();
break;
case ParserState.Depth:
if (int.Parse(Encoding.ASCII.GetString(token, 0, tokenSize)) != 255)
{
throw new InvalidOperationException("Not 255");
}
if (!Width.HasValue || !Height.HasValue)
{
throw new InvalidOperationException("Not all values filled in.");
}
state = ParserState.Data;
Buffer = new byte[Height.Value][][];
for (var iy = 0; iy < Height; iy++)
{
Buffer[iy] = new byte[Width.Value][];
for (var ix = 0; ix < Width; ix++)
{
Buffer[iy][ix] = new byte[3];
}
}
reset();
break;
}
}
token[tokenSize++] = (byte)nextByte;
}
}
}
}
}
class Program
{
static int Mod(int x, int m)
{
return (x % m + m) % m;
}
static void Main(string[] args)
{
var pl = new PpmLoader();
pl.Load(@"1.pbm");
// process - red blur
for (var y = 0; y < pl.Height; y++)
{
for (var x = 0; x < pl.Width; x++)
{
var swap = pl.Buffer[y][x][0];
pl.Buffer[y][x][0] = pl.Buffer[y][x][2];
pl.Buffer[y][x][2] = swap;
}
}
pl.Save(@"c:\cameron\x.ppm");
Console.WriteLine(pl.Width);
Console.WriteLine(pl.Height);
Console.Read();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment