summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatthewsotoudeh <matthewsot@outlook.com>2016-04-16 23:30:51 -0700
committermatthewsotoudeh <matthewsot@outlook.com>2016-04-16 23:30:51 -0700
commitf75c35a62ddaf5a0fd3f1226e3b6631a991a311d (patch)
tree27e6e93edb7124954d5b7902864f7a2bb6015d33
parentf9fea74563de525068331338bf5c9c7dccb0d30f (diff)
separated Writer code
-rw-r--r--NImg/NImg/Writer.cs83
1 files changed, 83 insertions, 0 deletions
diff --git a/NImg/NImg/Writer.cs b/NImg/NImg/Writer.cs
index c15cee1..ef1d2d2 100644
--- a/NImg/NImg/Writer.cs
+++ b/NImg/NImg/Writer.cs
@@ -1,5 +1,8 @@
using System;
+using System.Collections.Generic;
using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
using Zoltar;
namespace NImg
@@ -27,5 +30,85 @@ namespace NImg
}
}
}
+
+ public static void WriteImageMetadata(this BinaryWriter writer, int imageWidth, int imageHeight, int colorIndexBytes)
+ {
+ writer.Write(imageWidth);
+ writer.Write(imageHeight);
+ writer.Write(Convert.ToByte(colorIndexBytes));
+ }
+
+ public static void WriteAIByte(this BinaryWriter writer, int inARow)
+ {
+ //NOTE: 11110000 -> inARow = 1, not 0, increase by 1
+ // "Use AI" bytes are in the form 1111 + (number of pixels)
+ writer.Write(Convert.ToByte("1111" + Convert.ToString(inARow - 1, 2).PadLeft(4, '0'), 2));
+ }
+
+ public static void WriteColorIndex(this BinaryWriter writer, int colorIndexBytes, int colorIndex)
+ {
+ switch (colorIndexBytes)
+ {
+ case 1:
+ writer.Write(Convert.ToByte(colorIndex));
+ break;
+ case 2:
+ var byteStr = Convert.ToString(colorIndex, 2).PadLeft(16, '0');
+ writer.Write(Convert.ToByte(byteStr.Substring(0, 8), 2));
+ writer.Write(Convert.ToByte(byteStr.Substring(8), 2));
+ break;
+ }
+ }
+
+ public static void WriteColor(this BinaryWriter writer, int colorIndexBytes, List<int[]> colorList, int[] colorToWrite, BinaryWriter colorsWriter, int colorTolerance)
+ {
+ if (colorIndexBytes > 0)
+ {
+ var existing = colorList.FirstOrDefault(color =>
+ Math.Abs(colorToWrite[0] - color[0]) < colorTolerance &&
+ Math.Abs(colorToWrite[1] - color[1]) < colorTolerance &&
+ Math.Abs(colorToWrite[2] - color[2]) < colorTolerance);
+
+ var maxColorIndex = (colorIndexBytes == 1 ? 239 : 61440);
+
+ if (existing != null)
+ {
+ var index = colorList.IndexOf(existing);
+
+ writer.WriteColorIndex(colorIndexBytes, index);
+ }
+ else if (colorList.Count >= maxColorIndex)
+ {
+ //Over 239/61440 the byte starts with "1111", which is interpreted as a "Use AI" byte.
+ //At this point, just assume that the AI will give a better approximation of the accurate color
+ Console.WriteLine("Hit max colors, defaulting to AI");
+ writer.WriteAIByte(1);
+ }
+ else
+ {
+ //Add a new color to the dictionary
+ colorList.Add(colorToWrite);
+ colorsWriter.Write(Convert.ToByte(colorToWrite[0]));
+ colorsWriter.Write(Convert.ToByte(colorToWrite[1]));
+ colorsWriter.Write(Convert.ToByte(colorToWrite[2]));
+
+ writer.WriteColorIndex(colorIndexBytes, colorList.IndexOf(colorToWrite));
+ }
+ }
+ else
+ {
+ //Write the color to the file
+ for (var i = 0; i < colorToWrite.Length; i++)
+ {
+ var binaryStr = Convert.ToString(colorToWrite[0], 2);
+
+ //Any color component starting with 1111 will be interpreted as a "Use AI" bit, this is a hacky way to get around that
+ //This will drop any component above 239 by 16 units
+ binaryStr = Regex.Replace(binaryStr, "^1111", "1110");
+
+ writer.Write(Convert.ToByte(binaryStr, 2));
+ }
+ }
+ }
}
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback