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 }
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); } }