fork(3) download
  1. // Oleg Orlov, 2013(c) BMP reader C#
  2.  
  3. using System;
  4. using System.IO;
  5. using System.Text;
  6.  
  7. class BMPDataInfo
  8. {
  9. enum BMPHeaderTypes
  10. {
  11. BM, // Windows family
  12. BA, // OS/2 struct bitmap array
  13. CI, // OS/2 struct color icon
  14. CP, // OS/2 const color pointer
  15. IC, // OS/2 struct icon
  16. PT, // OS/2 pointer
  17. Invalid, // if two bytes from loaded file don't equal to any values of all BMP possible formats
  18. };
  19.  
  20. byte[] fileData;
  21. Encoding fileEncoding;
  22. BMPFileInfo fileInfo;
  23.  
  24. class BMPFileInfo
  25. {
  26. internal Encoding currentEncoding;
  27. internal BMPHeaderTypes currentBMPType;
  28. internal uint currentFileSize;
  29. internal int reservedFirst;
  30. internal int reservedSecond;
  31. internal int tablePixelStartAddress;
  32. internal int[] tablePixel;
  33. }
  34.  
  35. public BMPDataInfo()
  36. {
  37. fileInfo = new BMPFileInfo();
  38. }
  39.  
  40. internal byte[] ReadFile(string fileName)
  41. {
  42. FileStream fs = new FileStream(fileName, FileMode.Open);
  43. fileData = new byte[fs.Length];
  44. fs.Read(fileData, 0, fileData.Length);
  45. fs.Close();
  46.  
  47. using (var fileStreamReader = new StreamReader(fileName, true))
  48. {
  49. fileEncoding = fileStreamReader.CurrentEncoding;
  50. }
  51.  
  52. switch (fileEncoding.BodyName)
  53. {
  54. case "utf-8":
  55. fileInfo.currentEncoding = Encoding.UTF8;
  56. break;
  57. case "us-ascii":
  58. fileInfo.currentEncoding = Encoding.ASCII;
  59. break;
  60. }
  61.  
  62. return fileData;
  63. }
  64.  
  65. internal void BMPGetHeader()
  66. {
  67. #region Initializing the array size of 14 bytes for the BMP header
  68.  
  69. byte[] headerBMP = new byte[14];
  70.  
  71. for (int i = 0; i < headerBMP.Length; i++)
  72. {
  73. headerBMP[i] = fileData[i];
  74. }
  75.  
  76. #endregion
  77.  
  78. #region Getting first TWO bytes to check the type of BMP file format
  79.  
  80. fileInfo.currentBMPType = BMPCheckHeaderType(ref headerBMP[0], ref headerBMP[1]);
  81.  
  82. #endregion
  83.  
  84. #region Getting file size from BMP header, NOT from the `Length` property of stream
  85.  
  86. byte[] fileSizeHeaderInfo = new byte[4];
  87.  
  88. // needed fix for the correct byte shift (data[i] = i << shiftValue)
  89. for (int i = 2, j = 0; j < fileSizeHeaderInfo.Length; i++, j++)
  90. {
  91. fileSizeHeaderInfo[j] = fileData[i];
  92. }
  93.  
  94. fileInfo.currentFileSize = BMPGetFileSize(ref fileSizeHeaderInfo);
  95.  
  96. #endregion
  97.  
  98. #region Getting reserved fields from BMP header
  99.  
  100. byte[] fileReservedInfo = new byte[4];
  101.  
  102. for (int i = 6, j = 0; j < fileReservedInfo.Length; i++, j++)
  103. {
  104. fileReservedInfo[j] = fileData[i];
  105. }
  106.  
  107. int[] reservedResult = BMPGetReservedFromHeader(ref fileReservedInfo);
  108. fileInfo.reservedFirst = reservedResult[0];
  109. fileInfo.reservedSecond = reservedResult[1];
  110.  
  111. #endregion
  112.  
  113. #region Getting the starting address, of the byte where the bitmap image data (pixel array) can be found
  114.  
  115. byte[] filePixelArrayAddress = new byte[4];
  116.  
  117. for (int i = 10, j = 0; j < filePixelArrayAddress.Length; i++, j++)
  118. {
  119. filePixelArrayAddress[j] = fileData[i];
  120. }
  121.  
  122. fileInfo.tablePixelStartAddress = BMPGetStartAddress(ref filePixelArrayAddress);
  123.  
  124. #endregion
  125.  
  126. #region Reading the pixel table of the current BMP
  127.  
  128. // needed to be refactored, because the test BMP file has 24 bit depth color, so: 1 pixel/3 bytes
  129. fileInfo.tablePixel = new int[fileData.Length - fileInfo.tablePixelStartAddress];
  130. int[] bufferTable = new int[3];
  131.  
  132. for (int i = fileInfo.tablePixelStartAddress, j = 0, k = 0; i < fileInfo.tablePixel.Length; i++, k++)
  133. {
  134. if (k > 2)
  135. {
  136. int tmpValue = 0;
  137.  
  138. for (int z = 0; z < k; z++)
  139. {
  140. tmpValue += bufferTable[z];
  141. }
  142.  
  143. fileInfo.tablePixel[j] = tmpValue;
  144. k = 0;
  145. j++;
  146. i++;
  147. }
  148.  
  149. bufferTable[k] = fileData[i];
  150. }
  151.  
  152. #endregion
  153. }
  154.  
  155. BMPHeaderTypes BMPCheckHeaderType(ref byte firstValue, ref byte secondValue)
  156. {
  157. if (firstValue == 0x42 && secondValue == 0x4d)
  158. {
  159. return BMPHeaderTypes.BM;
  160. }
  161.  
  162. return BMPHeaderTypes.Invalid;
  163. }
  164.  
  165. uint BMPGetFileSize(ref byte[] headerPart)
  166. {
  167. uint fileSize = (uint)fileData[5] << 24
  168. | (uint)fileData[4] << 16
  169. | (uint)fileData[3] << 8
  170. | (uint)fileData[2];
  171.  
  172. return fileSize;
  173. }
  174.  
  175. int[] BMPGetReservedFromHeader(ref byte[] headerPart)
  176. {
  177. int reservedFirst = headerPart[0] + headerPart[1];
  178. int reservedSecond = headerPart[2] + headerPart[3];
  179.  
  180. int[] resultReserved = new int[2];
  181. resultReserved[0] = reservedFirst;
  182. resultReserved[1] = reservedSecond;
  183.  
  184. return resultReserved;
  185. }
  186.  
  187. int BMPGetStartAddress(ref byte[] headerPart)
  188. {
  189. int resultStartAddress = 0;
  190.  
  191. for (int i = 0; i < headerPart.Length; i++)
  192. {
  193. resultStartAddress += headerPart[i];
  194. }
  195.  
  196. return resultStartAddress;
  197. }
  198. }
  199.  
  200. class App
  201. {
  202. const string fileName = @"\1.bmp";
  203.  
  204. static void Main()
  205. {
  206. try
  207. {
  208. BMPDataInfo objDataInfo = new BMPDataInfo();
  209. objDataInfo.ReadFile(fileName);
  210. objDataInfo.BMPGetHeader();
  211. }
  212. catch (Exception exc)
  213. {
  214. Console.WriteLine(exc);
  215. }
  216. }
  217. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty