Beispiel #1
0
        public virtual void TestGetInt32()
        {
            Sharpen.Tests.AreEqual(-1, CreateReader(new sbyte[] { unchecked ((sbyte)0xff), unchecked ((sbyte)0xff), unchecked ((sbyte)0xff), unchecked ((sbyte)0xff) }).GetInt32());
            sbyte[]          buffer = new sbyte[] { unchecked ((int)(0x00)), unchecked ((int)(0x01)), unchecked ((int)(0x02)), unchecked ((int)(0x03)), unchecked ((int)(0x04)), unchecked ((int)(0x05)), unchecked ((int)(0x06)), unchecked ((int)(0x07)) };
            SequentialReader reader = CreateReader(buffer);

            Sharpen.Tests.AreEqual(unchecked ((int)(0x00010203)), reader.GetInt32());
            Sharpen.Tests.AreEqual(unchecked ((int)(0x04050607)), reader.GetInt32());
            reader = CreateReader(buffer);
            reader.SetMotorolaByteOrder(false);
            Sharpen.Tests.AreEqual(unchecked ((int)(0x03020100)), reader.GetInt32());
            Sharpen.Tests.AreEqual(unchecked ((int)(0x07060504)), reader.GetInt32());
        }
 public virtual void TestGetInt32_OutOfBounds()
 {
     try
     {
         SequentialReader reader = CreateReader(new sbyte[3]);
         reader.GetInt32();
         NUnit.Framework.Assert.Fail("Exception expected");
     }
     catch (IOException ex)
     {
         Sharpen.Tests.AreEqual("End of data reached.", ex.Message);
     }
 }
		/// <exception cref="Com.Drew.Imaging.Png.PngProcessingException"/>
		/// <exception cref="System.IO.IOException"/>
		public virtual Iterable<PngChunk> Extract(SequentialReader reader, ICollection<PngChunkType> desiredChunkTypes)
		{
			//
			// PNG DATA STREAM
			//
			// Starts with a PNG SIGNATURE, followed by a sequence of CHUNKS.
			//
			// PNG SIGNATURE
			//
			//   Always composed of these bytes: 89 50 4E 47 0D 0A 1A 0A
			//
			// CHUNK
			//
			//   4 - length of the data field (unsigned, but always within 31 bytes), may be zero
			//   4 - chunk type, restricted to [65,90] and [97,122] (A-Za-z)
			//   * - data field
			//   4 - CRC calculated from chunk type and chunk data, but not length
			//
			// CHUNK TYPES
			//
			//   Critical Chunk Types:
			//
			//     IHDR - image header, always the first chunk in the data stream
			//     PLTE - palette table, associated with indexed PNG images
			//     IDAT - image data chunk, of which there may be many
			//     IEND - image trailer, always the last chunk in the data stream
			//
			//   Ancillary Chunk Types:
			//
			//     Transparency information:  tRNS
			//     Colour space information:  cHRM, gAMA, iCCP, sBIT, sRGB
			//     Textual information:       iTXt, tEXt, zTXt
			//     Miscellaneous information: bKGD, hIST, pHYs, sPLT
			//     Time information:          tIME
			//
			reader.SetMotorolaByteOrder(true);
			// network byte order
			if (!Arrays.Equals(PngSignatureBytes, reader.GetBytes(PngSignatureBytes.Length)))
			{
				throw new PngProcessingException("PNG signature mismatch");
			}
			bool seenImageHeader = false;
			bool seenImageTrailer = false;
			IList<PngChunk> chunks = new AList<PngChunk>();
			ICollection<PngChunkType> seenChunkTypes = new HashSet<PngChunkType>();
			while (!seenImageTrailer)
			{
				// Process the next chunk.
				int chunkDataLength = reader.GetInt32();
				PngChunkType chunkType = new PngChunkType(reader.GetBytes(4));
				sbyte[] chunkData = reader.GetBytes(chunkDataLength);
				// Skip the CRC bytes at the end of the chunk
				// TODO consider verifying the CRC value to determine if we're processing bad data
				reader.Skip(4);
				if (seenChunkTypes.Contains(chunkType) && !chunkType.AreMultipleAllowed())
				{
					throw new PngProcessingException(Sharpen.Extensions.StringFormat("Observed multiple instances of PNG chunk '%s', for which multiples are not allowed", chunkType));
				}
				if (chunkType.Equals(PngChunkType.Ihdr))
				{
					seenImageHeader = true;
				}
				else
				{
					if (!seenImageHeader)
					{
						throw new PngProcessingException(Sharpen.Extensions.StringFormat("First chunk should be '%s', but '%s' was observed", PngChunkType.Ihdr, chunkType));
					}
				}
				if (chunkType.Equals(PngChunkType.Iend))
				{
					seenImageTrailer = true;
				}
				if (desiredChunkTypes == null || desiredChunkTypes.Contains(chunkType))
				{
					chunks.Add(new PngChunk(chunkType, chunkData));
				}
				seenChunkTypes.Add(chunkType);
			}
			return chunks.AsIterable();
		}
		public virtual void Extract(SequentialReader reader, Com.Drew.Metadata.Metadata metadata)
		{
			BmpHeaderDirectory directory = metadata.GetOrCreateDirectory<BmpHeaderDirectory>();
			// FILE HEADER
			//
			// 2 - magic number (0x42 0x4D = "BM")
			// 4 - size of BMP file in bytes
			// 2 - reserved
			// 2 - reserved
			// 4 - the offset of the pixel array
			//
			// BITMAP INFORMATION HEADER
			//
			// The first four bytes of the header give the size, which is a discriminator of the actual header format.
			// See this for more information http://en.wikipedia.org/wiki/BMP_file_format
			//
			// BITMAPINFOHEADER (size = 40)
			//
			// 4 - size of header
			// 4 - pixel width (signed)
			// 4 - pixel height (signed)
			// 2 - number of colour planes (must be set to 1)
			// 2 - number of bits per pixel
			// 4 - compression being used (needs decoding)
			// 4 - pixel data length (not total file size, just pixel array)
			// 4 - horizontal resolution, pixels/meter (signed)
			// 4 - vertical resolution, pixels/meter (signed)
			// 4 - number of colours in the palette (0 means no palette)
			// 4 - number of important colours (generally ignored)
			//
			// BITMAPCOREHEADER (size = 12)
			//
			// 4 - size of header
			// 2 - pixel width
			// 2 - pixel height
			// 2 - number of colour planes (must be set to 1)
			// 2 - number of bits per pixel
			//
			// COMPRESSION VALUES
			//
			// 0 = None
			// 1 = RLE 8-bit/pixel
			// 2 = RLE 4-bit/pixel
			// 3 = Bit field (or Huffman 1D if BITMAPCOREHEADER2 (size 64))
			// 4 = JPEG (or RLE-24 if BITMAPCOREHEADER2 (size 64))
			// 5 = PNG
			// 6 = Bit field
			reader.SetMotorolaByteOrder(false);
			try
			{
				int magicNumber = reader.GetUInt16();
				if (magicNumber != unchecked((int)(0x4D42)))
				{
					directory.AddError("Invalid BMP magic number");
					return;
				}
				// skip past the rest of the file header
				reader.Skip(4 + 2 + 2 + 4);
				int headerSize = reader.GetInt32();
				directory.SetInt(BmpHeaderDirectory.TagHeaderSize, headerSize);
				// We expect the header size to be either 40 (BITMAPINFOHEADER) or 12 (BITMAPCOREHEADER)
				if (headerSize == 40)
				{
					// BITMAPINFOHEADER
					directory.SetInt(BmpHeaderDirectory.TagImageWidth, reader.GetInt32());
					directory.SetInt(BmpHeaderDirectory.TagImageHeight, reader.GetInt32());
					directory.SetInt(BmpHeaderDirectory.TagColourPlanes, reader.GetInt16());
					directory.SetInt(BmpHeaderDirectory.TagBitsPerPixel, reader.GetInt16());
					directory.SetInt(BmpHeaderDirectory.TagCompression, reader.GetInt32());
					// skip the pixel data length
					reader.Skip(4);
					directory.SetInt(BmpHeaderDirectory.TagXPixelsPerMeter, reader.GetInt32());
					directory.SetInt(BmpHeaderDirectory.TagYPixelsPerMeter, reader.GetInt32());
					directory.SetInt(BmpHeaderDirectory.TagPaletteColourCount, reader.GetInt32());
					directory.SetInt(BmpHeaderDirectory.TagImportantColourCount, reader.GetInt32());
				}
				else
				{
					if (headerSize == 12)
					{
						directory.SetInt(BmpHeaderDirectory.TagImageWidth, reader.GetInt16());
						directory.SetInt(BmpHeaderDirectory.TagImageHeight, reader.GetInt16());
						directory.SetInt(BmpHeaderDirectory.TagColourPlanes, reader.GetInt16());
						directory.SetInt(BmpHeaderDirectory.TagBitsPerPixel, reader.GetInt16());
					}
					else
					{
						directory.AddError("Unexpected DIB header size: " + headerSize);
					}
				}
			}
			catch (IOException)
			{
				directory.AddError("Unable to read BMP header");
			}
		}