From ba93b57205b78af5c58043db3b46b51454c8ff10 Mon Sep 17 00:00:00 2001 From: David Neumaier Date: Thu, 15 Dec 2016 13:53:19 +0100 Subject: [PATCH] init --- App.config | 6 + PgmCreator.cs | 356 +++++++++++++++++++++++++++++++++++++ PgmCreatorDemo.cs | 93 ++++++++++ Program.cs | 14 ++ Properties/AssemblyInfo.cs | 36 ++++ font.pgm | Bin 0 -> 13672 bytes task_78.csproj | 60 +++++++ task_78.sln | 22 +++ 8 files changed, 587 insertions(+) create mode 100644 App.config create mode 100644 PgmCreator.cs create mode 100644 PgmCreatorDemo.cs create mode 100644 Program.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 font.pgm create mode 100644 task_78.csproj create mode 100644 task_78.sln diff --git a/App.config b/App.config new file mode 100644 index 0000000..8324aa6 --- /dev/null +++ b/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/PgmCreator.cs b/PgmCreator.cs new file mode 100644 index 0000000..d3c8dc6 --- /dev/null +++ b/PgmCreator.cs @@ -0,0 +1,356 @@ +using System; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +namespace Pgm { + + public enum PgmType { P2, P5 } + + public static class PgmCreator { + const byte NEW_LINE = 10; /* ascii code of new line */ + const byte HASH = 35; /* ascii code of hash: '#' */ + const byte SPACE = 32; /* ascii code of the blank / space */ + const byte ASCII_P = 80; + const byte ASCII_2 = 50; + const byte ASCII_5 = 53; + + #region PGM Reader + /// + /// Reads in a PGM file in P2 or P5 Format and returns a byte[,]-Array if everything works fine. Otherwise, exceptions are thrown. + /// For the specification of PGM-Files, see: http://netpbm.sourceforge.net/doc/pgm.html + /// + /// This Method was used and modified from http://www.cnblogs.com/lihongsheng0217/archive/2008/08/12/1266426.html + /// Original author: Mennan Tekbir(mtekbir[]gmail[]com). + /// Major modifications by Radomir Dinic and Gerhard Mitterlechner. License: GPL + /// + /// IMPORTANT: + /// *) A comment line must be present ofter the type code (P2 or P5). + /// *) Also: class only handles gray-values <= 255 correctly! (according to spec. <= 65536 should be supported) + /// *) Only newlines LF (ASCII 10) are used. Therefore, Windows users who create or modify the P2 PGM (=ASCII) files + /// MANUALLY may run into problems, because Windows OS uses CR (ASCII 13) AND NL (ASCII 10) for a line break. + /// + /// + /// + public static byte[,] ReadPgmFile(string filename) { + try { + FileStream inputStream; + BinaryReader pgmReader; + + inputStream = File.OpenRead(filename); + pgmReader = new BinaryReader(inputStream); + + byte[] pgmDataBuffer; //the actual image-data (width*height many elements) + int width, height; //dimension of the image + + using (inputStream) { //using two ressources, using can be nested + using (pgmReader) { + // stores some header info of PGM-File temporarily. + // WARNING: Here, the comment can be max. 999 characters long (plus the '#')! + byte[] tempArray = new byte[1000]; + + /* Sample PGM : (the dimension of the image is arbitrary, but the max-color value must be 255! (more strict than in specification!)) + * P2 + * # Created by ... + * 512 512 + * 255 + * [data] + */ + + //read PGM Type P2, P5 + tempArray[0] = pgmReader.ReadByte(); + if (tempArray[0] != ASCII_P) + throw new FormatException("Wrong first byte in pgm-File."); + + tempArray[1] = pgmReader.ReadByte(); + if (tempArray[1] != ASCII_2 && tempArray[1] != ASCII_5) + throw new FormatException("Wrong second byte in pgm-File."); + + //make a string out of first two read ASCII-Codes: + string sType = System.Text.ASCIIEncoding.Default.GetString(tempArray, 0, 2); + + //read until new line + while (pgmReader.ReadByte() != NEW_LINE) {;} + ReadComment(pgmReader, inputStream); + + width = Convert.ToInt32(ReadUntil(SPACE, pgmReader)); + height = Convert.ToInt32(ReadUntil(NEW_LINE, pgmReader)); + + if (width < 1 || width > 10000 || height < 1 || height > 10000) + throw new FormatException("Wrong values for width/height."); + + //read the maximal gray-scale color value (e.g., 255. Must be < 65536 according to the specification.) + //WARNING: this programm only allows a max color value of 255!!! + int maxColor = Convert.ToInt32(ReadUntil(NEW_LINE, pgmReader)); + if (maxColor > 255) + throw new FormatException("Max color value too high: must be <= 255."); + + //read image data + pgmDataBuffer = new byte[width * height]; + if (sType == "P5") + ReadP5(pgmDataBuffer, pgmReader); + else if (sType == "P2") + ReadP2(pgmDataBuffer, pgmReader); + + } //end inner using + } //end outer using + return CreateTwodimensionalArray(pgmDataBuffer, width, height); + } //end outer try + catch (FormatException) { + throw; //just rethrow it + } + catch (FileNotFoundException e) { //example of nested exception (same type) + throw new FileNotFoundException("File " + filename + " could not be found.", e); + } + catch (OutOfMemoryException e) { //example of nested exceptions (different type) + throw new ApplicationException("ReadPGMFile has got too little memory!", e); + } + catch (IOException e) { + throw new Exception("ReadPGMFile produced some IO-exception: " + e.Message); + } + catch (Exception e) { + throw new Exception("ReadPGMFile produced some exception: " + e.Message); + } + } + + //Read comments (if existI. Only one or no comment line is supported. + //Only length of max. 999 characters plus the '#'! + private static void ReadComment(BinaryReader pgmReader, FileStream inputStream) { + try { + byte tempByte = pgmReader.ReadByte(); + if (tempByte == HASH) + ReadUntil(NEW_LINE, pgmReader); + else //no comment ==> reset cursor + inputStream.Seek(-1, SeekOrigin.Current); + } + + catch (IOException e) { + throw new Exception("IO-Exception in ReadComment: " + e.Message); + } + catch (Exception e) { + throw new Exception("Error in ReadComment: " + e.Message); + } + } + + //Reads the image data for a P5 file into buffer. + private static void ReadP5(byte[] buffer, BinaryReader pgmReader) { + //If file is binary, read every byte + try { + //store each color value: + byte[] readBytes = pgmReader.ReadBytes(buffer.Length); + //copy the content to the destination buffer: + + Array.Copy(readBytes, buffer, readBytes.Length); + } + catch (Exception e) { + throw new Exception("Error reading binary data from P5 file! " + e.Message); + } + } + + //Reads the P2 image data to the buffer. + private static void ReadP2(byte[] buffer, BinaryReader pgmReader) { + //if file is text-based every pixel is distinguished by "space" + //and it has up to 3 chars (max grey-value of 255!) + try { + byte[] tempArray = new byte[1000]; + byte tempByte = pgmReader.ReadByte(); + int k = 0; + while (pgmReader.BaseStream.Position != pgmReader.BaseStream.Length) { + //read all non-newline or non-whitespace character + int i = 0; + while (tempByte != NEW_LINE && tempByte != SPACE) { + tempArray[i] = tempByte; + i++; + tempByte = pgmReader.ReadByte(); + } + //Convert the non-newline/non-whitespace characters to a string and + //copy the string representation of every pixel to buffer of image data. + buffer[k] = Convert.ToByte(System.Text.ASCIIEncoding.Default.GetString(tempArray, 0, i)); + k++; + + tempByte = pgmReader.ReadByte(); + if (pgmReader.BaseStream.Position != pgmReader.BaseStream.Length) { + if (tempByte == NEW_LINE || tempByte == SPACE) { + tempByte = pgmReader.ReadByte(); //read next character (must be a non-newline/non-blank) + } + } + } //end while + } //end try + catch (EndOfStreamException e) { + //if premature end of stream is reached... + throw new Exception("Unexcpected end of stream reading P2 file: " + e.Message); + } + catch (IOException e) { + throw new Exception("Some IO exception when reading P2 file: " + e.Message); + } + catch (Exception e){ + throw new Exception("Some other exception when reading P2 file: " + e.Message); + } + } + + //Reads from pgmReader until separator is reached. (Max 1000 bytes.) + private static string ReadUntil(byte separator, BinaryReader pgmReader) { + try { + byte[] tempArray = new byte[1000]; + int i = 0; + byte tempByte = pgmReader.ReadByte(); + while (tempByte != separator) { + tempArray[i] = tempByte; + i++; + tempByte = pgmReader.ReadByte(); + } + //make a string out of tempArray + return System.Text.ASCIIEncoding.Default.GetString(tempArray, 0, i); + } + catch (IndexOutOfRangeException) { + throw new IndexOutOfRangeException("ReadUntil failed: wrong indices in while-loop."); + } + catch (Exception e) { + throw new Exception("ReadUntil failed: " + e.Message); + } + } + + //Creates a two-dim array out of the one-dim pgmDataBuffer. + private static byte[,] CreateTwodimensionalArray(byte[] pgmDataBuffer, int width, int height) { + try { + byte[,] temp = new byte[width, height]; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + temp[x, y] = pgmDataBuffer[y * width + x]; + } + } + return temp; + } + catch (OutOfMemoryException e) { + throw new OutOfMemoryException("CreateTwodimensionalArray failed: too little memory.", e); + } + catch (IndexOutOfRangeException) { + throw new Exception("Wrong index in for-loop of CreateTwodimensionalArray."); + } + catch (Exception e) { + throw new Exception("CreateTwodimensionalArray failed: " + e.Message); + } + } + + #endregion + + #region PGM Writer + /// + /// Write a given byte[,] to Pgm-File or throws an exception on an error. + /// Formats: + /// P2: ASCII-Format + /// P5: Binary-Format + /// + /// filename or path + /// array with image-data + /// Type P2 or P5 + public static void WritePgmFile(string filename, byte[,] imgData, PgmType type) { + if (imgData == null) + throw new ArgumentException("WritePgmFileBinary: imgData must not be null."); + + switch (type) { + case PgmType.P2: + WritePgmFileASCII(filename, imgData, type); + break; + case PgmType.P5: + WritePgmFileBinary(filename, imgData, type); + break; + default: + throw new ArgumentException("WritePgmFile failed: wrong type!"); + } + } + + //helper for WritePgmFile + private static void WritePgmFileASCII(string filename, byte[,] imgData, PgmType type) { + StreamWriter writer = null; + try { + writer = new StreamWriter(filename); + writer.Write(BuildPgmHeader(imgData.GetLength(0), imgData.GetLength(1), type)); + + for (int y = 0; y < imgData.GetLength(1); y++) { + for (int x = 0; x < imgData.GetLength(0); x++) { + string data = imgData[x, y].ToString() + " "; + writer.Write(data); + } + writer.Write('\n'); + } + } + catch (UnauthorizedAccessException e) { + throw new Exception("WritePgmFile failed: no permission to write. " + e.Message); + } + catch (Exception e) { + throw new Exception("WritePgmFileASCII failed: could not write to file " + filename + ". " + e.Message); + } + finally { //example using finally (instead of "using") + if (writer != null) writer.Close(); + } + } + + //helper for WritePgmFile + private static void WritePgmFileBinary(string filename, byte[,] imgData, PgmType type) { + try { + FileStream outputStream = File.Create(filename); + BinaryWriter pgmWriter = new BinaryWriter(outputStream); + using (outputStream) { + using (pgmWriter) { + string PGMInfo = BuildPgmHeader(imgData.GetLength(0), imgData.GetLength(1), type); + byte[] PGMInfoBuffer = System.Text.ASCIIEncoding.Default.GetBytes(PGMInfo); + pgmWriter.Write(PGMInfoBuffer); + byte[] temp = CreateOneDimensionalTempArray(imgData); + pgmWriter.Write(temp); + } + } + } + catch (IOException e) { + throw new Exception("IOException in WritePgmFileBinary writing to file: " + filename + ". " + e.Message); + } + catch (OutOfMemoryException e) { + throw new Exception("WritePgmFile failed with OutOfMemoryException: " + e.Message); + } + catch (UnauthorizedAccessException e) { + throw new Exception("WritePgmFile failed: no permission to write. " + e.Message); + } + } + + private static string BuildPgmHeader(int width, int height, PgmType type) { + string header = string.Empty; + switch (type) { + case PgmType.P2: + header += "P2\n"; + break; + case PgmType.P5: + header += "P5\n"; + break; + default: + throw new ArgumentException("Wrong type in BuildPgmHeader."); + } + header += "# MMT\n"; + header += width + " " + height + "\n"; + header += "255\n"; //warning: this is hardcoded, should allow a value up to 65535 according to specification! + return header; + } + + private static byte[] CreateOneDimensionalTempArray(byte[,] imgData) { + if (imgData == null) + throw new ArgumentException("CreateOneDimensionalTempArray: imgData must not be null."); + int w = imgData.GetLength(0); + int h = imgData.GetLength(1); + try { + byte[] temp = new byte[w * h]; + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + temp[y * w + x] = imgData[x, y]; + } + } + return temp; + } + catch (OutOfMemoryException e) { + throw new OutOfMemoryException("CreateOneDimensionalTempArray failed. Too little memory! " + e.Message); + } + catch (Exception e) { + throw new Exception("CreateOneDimensionalTempArray failed.", e); + } + } + #endregion + } +} diff --git a/PgmCreatorDemo.cs b/PgmCreatorDemo.cs new file mode 100644 index 0000000..990b4fb --- /dev/null +++ b/PgmCreatorDemo.cs @@ -0,0 +1,93 @@ +using System; +using System.IO; +using System.Diagnostics; +using Pgm; + +class PgmCreatorDemo { + + //TYPICAL USAGE OF THE PGMCREATOR CLASS: + static void MakeLenaBlackWhite() { + // for the specification of PGM-Files, see: http://netpbm.sourceforge.net/doc/pgm.html + + // A byte-array is used for storing the gray-color-values. + // The img has the size 256x256 pixel; + // Each pixel has a gray-color-value from 0-255 (0...black, 255...white). + // Note also that the FIRST dimension (row-index) corresponds + // to the x-Coordinate (!!!) in the image, the second dimension (col-index) + // to the y-coordinate (!!!). The y coordinate goes from up to down! + // Thus, an index of [50, 250] is at the left and bottom of the image. + // (The Write/ReadPGM-Methods internally transpose the matrix.) + + // Open Lena, make it black-white (threshold is the value 128), and save it: + try { + byte[,] lenaImgData = PgmCreator.ReadPgmFile("lena.pgm"); + for (int x = 0; x < lenaImgData.GetLength(0); x++) { + for (int y = 0; y < lenaImgData.GetLength(1); y++) { + if (lenaImgData[x, y] < 128) lenaImgData[x, y] = 0; + else lenaImgData[x, y] = 255; + } + } + PgmCreator.WritePgmFile("lena_black_white.pgm", lenaImgData, PgmType.P5); + Console.WriteLine("Success making Lena black-white!"); + } + catch (FileNotFoundException e) { + Console.WriteLine("Where ist the file? " + e.Message); + } + catch (FormatException e) { + Console.WriteLine("Wrong file format: " + e.Message); + } + catch (Exception e) { + Console.WriteLine(e.Message); + } + } + + static void Main(string[] args) { + TestBinaryAndASCIIFormat(); + MakeLenaBlackWhite(); + } + + //Helper Method which produces a byte-array representing a gradient image: + private static byte[,] ProduceGradientImage() { + byte[,] imgData = new byte[256, 256]; + + // fill the imgData-Array with the gray-color-values: + for (int y = 0; y < imgData.GetLength(1); y++) { + for (int x = 0; x < imgData.GetLength(0); x++) { + // produce a gray-color gradient image: + // top-left corner: black, bottom-right corner: white. + // Note that x and y go from 0 to 255, so x/2 + y/2 cannot exceed the value 254. + imgData[x, y] = (byte)(x / 2 + y / 2); + } + } + return imgData; + } + + //Tests whether both pgm file formats work: + private static void TestBinaryAndASCIIFormat() { + byte[,] imgData = ProduceGradientImage(); + + byte[,] readDataAscii; + byte[,] readDataBinary; + try { + // write imgData to P2 file (ascii): + PgmCreator.WritePgmFile("testASCII.pgm", imgData, PgmType.P2); + // read from P2 file (ascii): + readDataAscii = PgmCreator.ReadPgmFile("testASCII.pgm"); + // write image data to P5 file (binary): + PgmCreator.WritePgmFile("testBinary.pgm", readDataAscii, PgmType.P5); + // read P5 file (binary): + readDataBinary = PgmCreator.ReadPgmFile("testBinary.pgm"); + + //check if the image loaded from the P2-type file (ascii) + //is the same as from the P5-type file (binary): + for (int y = 0; y < imgData.GetLength(1); y++) { + for (int x = 0; x < imgData.GetLength(0); x++) { + Debug.Assert(readDataAscii[x,y] == readDataBinary[x,y]); + } + } + Console.WriteLine("Success in testing two generated files of both types!"); + } catch (Exception e) { + Console.WriteLine(e.Message); + } + } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..20cb8d1 --- /dev/null +++ b/Program.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace task_78 +{ + class Program + { + static void Main(string[] args) { + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d30d688 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("task_78")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("task_78")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ddc7d81a-b435-4906-9a02-b2560d46f755")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/font.pgm b/font.pgm new file mode 100644 index 0000000000000000000000000000000000000000..dae4361e81f8e586bc3daba24dee927a405a93db GIT binary patch literal 13672 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 literal 0 HcmV?d00001 diff --git a/task_78.csproj b/task_78.csproj new file mode 100644 index 0000000..ffb349e --- /dev/null +++ b/task_78.csproj @@ -0,0 +1,60 @@ + + + + + Debug + AnyCPU + {DDC7D81A-B435-4906-9A02-B2560D46F755} + Exe + Properties + task_78 + task_78 + v4.6 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/task_78.sln b/task_78.sln new file mode 100644 index 0000000..21a4e54 --- /dev/null +++ b/task_78.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "task_78", "task_78.csproj", "{DDC7D81A-B435-4906-9A02-B2560D46F755}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DDC7D81A-B435-4906-9A02-B2560D46F755}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDC7D81A-B435-4906-9A02-B2560D46F755}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDC7D81A-B435-4906-9A02-B2560D46F755}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDC7D81A-B435-4906-9A02-B2560D46F755}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal