/// <summary> /// Sets four-byte IBM float to the buffer (IBM is always Big-Endian) /// </summary> /// <param name="value"></param> /// <param name="offset"></param> public static void SetBytesIBM(byte[] Buffer, NumberUnion fu, float value, int offset) { if (Buffer == null) { return; } fu.f = value; Buffer[offset] = 0x00; Buffer[offset + 1] = 0x00; Buffer[offset + 2] = 0x00; Buffer[offset + 3] = 0x00; // if the content of the source 4 bytes is already zeros, skip the pass if (fu.i32 == 0) { return; } // perform calculations on mantissa and exponent uint mantissa = (0x007fffff & fu.ui32) | 0x00800000; uint exponent = ((0x7f800000 & fu.ui32) >> 23) - 126; while ((exponent & 0x3) != 0) { ++exponent; mantissa >>= 1; }//while fu.ui32 = (0x80000000 & fu.ui32) | (((exponent >> 2) + 64) << 24) | mantissa; // write to the destination, maintaining the "big-endian" order Buffer[offset] = fu.b3; Buffer[offset + 1] = fu.b2; Buffer[offset + 2] = fu.b1; Buffer[offset + 3] = fu.b0; }
/// <summary> /// Sets one byte /// </summary> /// <param name="buffer"></param> /// <param name="value"></param> /// <param name="offset"></param> public static void SetByte(byte[] Buffer, NumberUnion fu, byte value, int offset) { if (Buffer == null) { return; } Buffer[offset] = value; }
private void MakeIFDEntry(byte[] buff, int index, ushort code, ushort type, uint count, uint val) { NumberUnion nu = new NumberUnion(); int offset = index * 12 + 10; BufferConverter.SetBytesUInt16(buff, nu, code, offset); // code BufferConverter.SetBytesUInt16(buff, nu, type, offset + 2); // type BufferConverter.SetBytesUInt32(buff, nu, count, offset + 4); // count BufferConverter.SetBytesUInt32(buff, nu, val, offset + 8); // value }
/// <summary> /// Sets two-byte integer to the buffer (Big-Endian) /// </summary> /// <param name="value"></param> /// <param name="offset"></param> public static void SetBytesUInt16_BE(byte[] Buffer, NumberUnion fu, UInt16 value, int offset) { if (Buffer == null) { return; } fu.i32 = 0; fu.ui16 = value; Buffer[offset + 1] = fu.b0; Buffer[offset] = fu.b1; }
/// <summary> /// Sets four-byte integer to the buffer (Big-Endian) /// </summary> /// <param name="value"></param> /// <param name="offset"></param> public static void SetBytesUInt32_BE(byte[] Buffer, NumberUnion fu, UInt32 value, int offset) { if (Buffer == null) { return; } fu.ui32 = value; Buffer[offset + 3] = fu.b0; Buffer[offset + 2] = fu.b1; Buffer[offset + 1] = fu.b2; Buffer[offset] = fu.b3; }
/// <summary> /// Sets four-byte float to the buffer (Big-Endian) /// </summary> /// <param name="value"></param> /// <param name="offset"></param> public static void SetBytesFloat_BE(byte[] Buffer, NumberUnion fu, float value, int offset) { if (Buffer == null) { return; } fu.f = value; Buffer[offset + 3] = fu.b0; Buffer[offset + 2] = fu.b1; Buffer[offset + 1] = fu.b2; Buffer[offset] = fu.b3; }
/// <summary> /// Sets the bytes in the buffer to the string values /// </summary> /// <param name="buffer"></param> /// <param name="value"></param> /// <param name="length"></param> /// <param name="offset"></param> public static void SetBytesString(byte[] Buffer, NumberUnion fu, string value, int length, int offset) { if (Buffer == null) { return; } for (int i = 0; i < length; i++) { Buffer[offset + i] = (byte)0x00; } for (int i = 0; i < value.Length; i++) { Buffer[offset + i] = Convert.ToByte(value[i]); } }
/// <summary> /// Returns two-byte integer from the buffer (Big-Endian) /// </summary> /// <param name="offset"></param> /// <returns></returns> public static UInt16 GetBytesUInt16_BE(byte[] Buffer, NumberUnion fu, int offset) { if (Buffer == null) { return(0); } fu.b0 = Buffer[offset + 1]; fu.b1 = Buffer[offset]; fu.b2 = 0; fu.b3 = 0; fu.b4 = 0; fu.b5 = 0; fu.b6 = 0; fu.b7 = 0; return(fu.ui16); }
/// <summary> /// Returns four-byte integer from the buffer (Big-Endian) /// </summary> /// <param name="offset"></param> /// <returns></returns> public static Int32 GetBytesInt32_BE(byte[] Buffer, NumberUnion fu, int offset) { if (Buffer == null) { return(0); } fu.b0 = Buffer[offset + 3]; fu.b1 = Buffer[offset + 2]; fu.b2 = Buffer[offset + 1]; fu.b3 = Buffer[offset]; fu.b4 = 0; fu.b5 = 0; fu.b6 = 0; fu.b7 = 0; return(fu.i32); }
/// <summary> /// Returns four-byte float from the buffer (Big-Endian) /// </summary> /// <param name="offset"></param> /// <returns></returns> public static float GetBytesFloat_BE(byte[] Buffer, NumberUnion fu, int offset) { if (Buffer == null) { return(0.0f); } fu.b0 = Buffer[offset + 3]; fu.b1 = Buffer[offset + 2]; fu.b2 = Buffer[offset + 1]; fu.b3 = Buffer[offset]; fu.b4 = 0; fu.b5 = 0; fu.b6 = 0; fu.b7 = 0; return(fu.f); }
/// <summary> /// Sets eight-byte double to the buffer (Big-Endian) /// </summary> /// <param name="value"></param> /// <param name="offset"></param> public static void SetBytesDouble_BE(byte[] Buffer, NumberUnion fu, double value, int offset) { if (Buffer == null) { return; } fu.d = value; Buffer[offset + 7] = fu.b0; Buffer[offset + 6] = fu.b1; Buffer[offset + 5] = fu.b2; Buffer[offset + 4] = fu.b3; Buffer[offset + 3] = fu.b4; Buffer[offset + 2] = fu.b5; Buffer[offset + 1] = fu.b6; Buffer[offset] = fu.b7; }
/// <summary> /// Returns eight-byte double from the buffer (Big-Endian) /// </summary> /// <param name="offset"></param> /// <returns></returns> public static double GetBytesDouble_BE(byte[] Buffer, NumberUnion fu, int offset) { if (Buffer == null) { return(0.0f); } fu.b0 = Buffer[offset + 7]; fu.b1 = Buffer[offset + 6]; fu.b2 = Buffer[offset + 5]; fu.b3 = Buffer[offset + 4]; fu.b4 = Buffer[offset + 3]; fu.b5 = Buffer[offset + 2]; fu.b6 = Buffer[offset + 1]; fu.b7 = Buffer[offset]; return(fu.d); }
/// <summary> /// Gets the string from the buffer /// </summary> /// <param name="length"></param> /// <param name="offset"></param> /// <returns></returns> public static string GetEBCDICBytesString(byte[] Buffer, NumberUnion fu, int length, int offset) { if (Buffer == null) { return(""); } Decoder dec = Encoding.GetEncoding(37).GetDecoder(); char[] buff = new char[length]; dec.GetChars(Buffer, offset, length, buff, 0, true); StringBuilder sb = new StringBuilder(); for (int i = 0; i < buff.Length; i++) { sb.Append(buff[i]); } return(sb.ToString()); }
/// <summary> /// Returns four-byte IBM float from the buffer (IBM is always Big-endian) /// </summary> /// <param name="offset"></param> /// <returns></returns> public static float GetBytesIBM(byte[] Buffer, NumberUnion fu, int offset) { if (Buffer == null) { return(0.0f); } // swap bytes from the IBM order ("big endian") to the PC order fu.b3 = Buffer[offset]; fu.b2 = Buffer[offset + 1]; fu.b1 = Buffer[offset + 2]; fu.b0 = Buffer[offset + 3]; // if the content of the Buffer 4 bytes is already zeros, skip the pass if (fu.i32 == 0) { return(0.0f); } // detect mantissa and exponent uint mantissa = 0x00ffffff & fu.ui32; uint exponent = ((0x7f000000 & fu.ui32) >> 22) - 130; while (mantissa != 0 && (mantissa & 0x00800000) == 0) { --exponent; mantissa <<= 1; } // perform number checks if (exponent > 254 && mantissa != 0) { fu.ui32 = (0x80000000 & fu.ui32) | 0x7f7fffff; } else if (exponent <= 0 || mantissa == 0) { fu.ui32 = 0; } else { fu.ui32 = (0x80000000 & fu.ui32) | (exponent << 23) | (0x007fffff & mantissa); } return(fu.f); }
/// <summary> /// Gets the string from the buffer /// </summary> /// <param name="length"></param> /// <param name="offset"></param> /// <returns></returns> public static string GetBytesString(byte[] Buffer, NumberUnion fu, int length, int offset) { if (Buffer == null) { return(null); } StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { byte b = Buffer[offset + i]; if (b == 0) { break; } sb.Append(Convert.ToChar(b)); } return(sb.ToString()); }
/// <summary> /// Sets the bytes in the buffer to the string values /// </summary> /// <param name="buffer"></param> /// <param name="value"></param> /// <param name="length"></param> /// <param name="offset"></param> public static void SetEBCDICBytesString(byte[] Buffer, NumberUnion fu, string value, int length, int offset) { if (Buffer == null) { return; } char[] buff = new char[length]; for (int i = 0; i < length; i++) { buff[i] = ' '; } for (int i = 0; i < value.Length && i < length; i++) { buff[i] = value[i]; } Encoder enc = Encoding.GetEncoding(37).GetEncoder(); enc.GetBytes(buff, 0, length, Buffer, offset, true); }
private void SetBMPHeader() { NumberUnion fu = new NumberUnion(); uint size = ImageSizeBMP + (uint)BMPHeader.Length; // file size is composed of the pixel length and the header BufferConverter.SetBytesString(BMPHeader, fu, "BM", 2, 0); // first two bytes are always BM BufferConverter.SetBytesUInt32(BMPHeader, fu, size, 2); // file length BufferConverter.SetBytesInt32(BMPHeader, fu, BMPHeader.Length, 10); // data start BufferConverter.SetBytesUInt32(BMPHeader, fu, 40, 14); // size of DIB header BufferConverter.SetBytesUInt32(BMPHeader, fu, m_x, 18); // width BufferConverter.SetBytesUInt32(BMPHeader, fu, m_y, 22); // height BufferConverter.SetBytesUInt16(BMPHeader, fu, 1, 26); // color planes = 1 BufferConverter.SetBytesUInt16(BMPHeader, fu, 24, 28); // bits per pixel BufferConverter.SetBytesUInt32(BMPHeader, fu, 0, 30); // no compression BufferConverter.SetBytesUInt32(BMPHeader, fu, ImageSizeBMP, 34); // raw image size BufferConverter.SetBytesUInt32(BMPHeader, fu, 11811, 38); // horizontal bits per meter 300 dpi BufferConverter.SetBytesUInt32(BMPHeader, fu, 11811, 42); // vertical bits per meter 300 dpi BufferConverter.SetBytesUInt32(BMPHeader, fu, 0, 46); // default color palette BufferConverter.SetBytesUInt32(BMPHeader, fu, 0, 50); // important colors, ignored }
private void SetTIFHeader() { NumberUnion nu = new NumberUnion(); // the TIFF header length for a single-page file is defined as following // 8-bit magic header // first IFD = 2 bytes + nValues*12 + 4 bytes // 3 * 2 bytes for the bit per sample // 2 * 8 bytes for the DPI resolution // Copyright + 1 null byte // Row start addresses 4 bytes * image height // Row lenghts 4 bytes * image height int cIFDentries = 17; long bufLength = 8 + 2 + (long)cIFDentries * 12 + 4 + 6 + 16 + (long)m_Copyright.Length + 1 + (long)m_y * 8; TIFHeader = new byte[bufLength]; // Write magic number. Note the 42 - the Meaning of Life, Universe and Everything BufferConverter.SetBytesString(TIFHeader, nu, "II", 2, 0); // Little endian BufferConverter.SetBytesUInt16(TIFHeader, nu, 42, 2); // Meaning of life BufferConverter.SetBytesUInt32(TIFHeader, nu, 8, 4); // Address of IFD // Write IFD // 8 bytes in the magic number, 2 bytes in IFD length, and 4 bytes in the next address uint cIFDboundary = (uint)(12 * cIFDentries) + 14; // 6 bytes for bits, 16 bytes for DPI, and the Copyrigtht uint cListBoundary = cIFDboundary + 22 + (uint)m_Copyright.Length + 1; BufferConverter.SetBytesInt16(TIFHeader, nu, (short)cIFDentries, 8); // number of entries // Write IFD entries MakeIFDEntry(TIFHeader, 0, 254, 4, 1, 2); // apparently needed MakeIFDEntry(TIFHeader, 1, 256, 4, 1, (uint)m_x); // x size MakeIFDEntry(TIFHeader, 2, 257, 4, 1, (uint)m_y); // y size MakeIFDEntry(TIFHeader, 3, 258, 3, 3, cIFDboundary); // points to the bit per sample MakeIFDEntry(TIFHeader, 4, 259, 3, 1, 1); // no compression - flat file MakeIFDEntry(TIFHeader, 5, 262, 3, 1, 2); // photometric MakeIFDEntry(TIFHeader, 6, 273, 4, m_y, cListBoundary); // offset strips MakeIFDEntry(TIFHeader, 7, 274, 3, 1, 1); // image orientation MakeIFDEntry(TIFHeader, 8, 277, 3, 1, 3); // samples per pixel MakeIFDEntry(TIFHeader, 9, 278, 3, 1, 1); // rows per strip MakeIFDEntry(TIFHeader, 10, 279, 4, m_y, cListBoundary + m_y * 4); // strip lengths MakeIFDEntry(TIFHeader, 11, 282, 5, 1, cIFDboundary + 6); // X_resoltion MakeIFDEntry(TIFHeader, 12, 283, 5, 1, cIFDboundary + 14); // Y_resoltion MakeIFDEntry(TIFHeader, 13, 284, 3, 1, 1); // chunky format MakeIFDEntry(TIFHeader, 14, 296, 3, 1, 2); // dimension in cm=3 MakeIFDEntry(TIFHeader, 15, 297, 3, 2, 0); // page orger MakeIFDEntry(TIFHeader, 16, 33432, 2, (uint)m_Copyright.Length + 1, cIFDboundary + 22); // copyright // close IFD BufferConverter.SetBytesInt32(TIFHeader, nu, 0, (int)cIFDboundary - 4); // no next IDF // now write parameters BufferConverter.SetBytesInt16(TIFHeader, nu, 8, (int)cIFDboundary); // 3 times 8 for bit per sample BufferConverter.SetBytesInt16(TIFHeader, nu, 8, (int)cIFDboundary + 2); BufferConverter.SetBytesInt16(TIFHeader, nu, 8, (int)cIFDboundary + 4); BufferConverter.SetBytesInt32(TIFHeader, nu, m_resNumerator, (int)cIFDboundary + 6); BufferConverter.SetBytesInt32(TIFHeader, nu, m_resDenominator, (int)cIFDboundary + 10); BufferConverter.SetBytesInt32(TIFHeader, nu, m_resNumerator, (int)cIFDboundary + 14); BufferConverter.SetBytesInt32(TIFHeader, nu, m_resDenominator, (int)cIFDboundary + 18); BufferConverter.SetBytesString(TIFHeader, nu, m_Copyright, m_Copyright.Length, (int)cIFDboundary + 22); // now write the addresses and offsets long blen = (long)m_y * 4; uint rowSize = (uint)m_x * 3; uint startPosition = cListBoundary + m_y * 8; for (int i = 0; i < blen; i += 4) { BufferConverter.SetBytesUInt32(TIFHeader, nu, startPosition, (int)cListBoundary + i); startPosition += rowSize; } cListBoundary += m_y * 4; for (int i = 0; i < blen; i += 4) { BufferConverter.SetBytesUInt32(TIFHeader, nu, rowSize, (int)cListBoundary + i); } }