/// <summary> /// Extracts various fields specific to this chunk from the APNG's /// data field /// </summary> /// <param name="chunkData">An array of bytes representing the APNG's data field</param> protected override void ParseData(byte[] chunkData) { int offset = 0; frameWidth = APNGUtility.ParseUint(chunkData, 4, ref offset); frameHeight = APNGUtility.ParseUint(chunkData, 4, ref offset); //ticksPerSecond = APNGUtility.ParseUint(chunkData, 4, ref offset); //nominalLayerCount = APNGUtility.ParseUint(chunkData, 4, ref offset); //nominalFrameCount = APNGUtility.ParseUint(chunkData, 4, ref offset); //nominalPlayTime = APNGUtility.ParseUint(chunkData, 4, ref offset); //simplicityProfile = APNGUtility.ParseUint(chunkData, 4, ref offset); }
/// <summary> /// Extracts various fields specific to this chunk from the APNG's /// data field /// </summary> /// <param name="chunkData">An array of bytes representing the APNG's data field</param> protected override void ParseData(byte[] chunkData) { int offset = 0; width = APNGUtility.ParseUint(chunkData, 4, ref offset); height = APNGUtility.ParseUint(chunkData, 4, ref offset); bitDepth = APNGUtility.ParseUint(chunkData, 1, ref offset); colorType = APNGUtility.ParseUint(chunkData, 1, ref offset); compressionMethod = APNGUtility.ParseUint(chunkData, 1, ref offset); filterMethod = APNGUtility.ParseUint(chunkData, 1, ref offset); interlaceMethod = APNGUtility.ParseUint(chunkData, 1, ref offset); }
/// <summary> /// Extracts various fields specific to this chunk from the APNG's /// data field /// </summary> /// <param name="chunkData">An array of bytes representing the APNG's data field</param> protected override void ParseData(byte[] chunkData) { int offset = 0; terminationAction = APNGUtility.ParseUint(chunkData, 1, ref offset); // If the data length is > 1 then read 9 more bytes if (chunkData.Length > 1) { actionAfterTermination = APNGUtility.ParseUint(chunkData, 1, ref offset); delay = APNGUtility.ParseUint(chunkData, 4, ref offset); iterationMax = APNGUtility.ParseUint(chunkData, 4, ref offset); } }
/// <summary> /// Attempts to parse an APNGChunk for the specified stream /// </summary> /// <param name="stream">The stream containing the APNG Chunk</param> public void Read(Stream stream) { if (!stream.CanRead) { throw new ArgumentException("Stream is not readable"); } calculatedCRC = CRC.INITIAL_CRC; long chunkStart = stream.Position; // Read the data Length chunkLength = APNGUtility.ReadStream(stream, 4); // Read the chunk type chunkType = APNGUtility.ReadStream(stream, 4); calculatedCRC = CRC.UpdateCRC(calculatedCRC, chunkType); // Read the data chunkData = APNGUtility.ReadStream(stream, ChunkLength); calculatedCRC = CRC.UpdateCRC(calculatedCRC, chunkData); // Read the CRC chunkCRC = APNGUtility.ReadStream(stream, 4); // CRC is inverted calculatedCRC = ~calculatedCRC; // Verify the CRC if (ChunkCRC != calculatedCRC) { StringBuilder sb = new StringBuilder(); sb.AppendLine(String.Format("APNG Chunk CRC Mismatch. Chunk CRC = {0}, Calculated CRC = {1}.", ChunkCRC, calculatedCRC)); sb.AppendLine(String.Format("This occurred while parsing the chunk at position {0} (0x{1:X8}) in the stream.", chunkStart, chunkStart)); throw new ApplicationException(sb.ToString()); } }
/// <summary> /// Attempts to read an APNG Header chunk from the supplied stream. /// </summary> /// <param name="stream">The stream containing the APNG Header</param> public void Read(Stream stream) { // Stream must be readable if (!stream.CanRead) { throw new ArgumentException("Stream is not readable"); } // Read the signature try { signature = APNGUtility.ReadStream(stream, 8); } catch (Exception) { // Re-throw any exceptions throw; } // Test signature for validity if (signature.Length == expectedSignature.Length) { for (int i = 0; i < expectedSignature.Length; i++) { // Invalid signature if (expectedSignature[i] != signature[i]) { throw new ApplicationException("APNG signature not found."); } } } else { // Invalid signature throw new ApplicationException("APNG signature not found."); } }
/// <summary> /// Extracts various fields specific to this chunk from the APNG's /// data field /// </summary> /// <param name="chunkData">An array of bytes representing the APNG's data field</param> protected override void ParseData(byte[] chunkData) { int offset = 0; redBackground = APNGUtility.ParseUint(chunkData, 2, ref offset); greenBackground = APNGUtility.ParseUint(chunkData, 2, ref offset); blueBackground = APNGUtility.ParseUint(chunkData, 2, ref offset); // If the data length is > 6 then read 1 more byte if (chunkData.Length > 6) { mandatoryBackground = APNGUtility.ParseUint(chunkData, 1, ref offset); } // If the data length is > 7 then read 2 more bytes if (chunkData.Length > 7) { backgroundImageId = APNGUtility.ParseUint(chunkData, 2, ref offset); } // If the data length is > 9 then read 1 more byte if (chunkData.Length > 9) { backgroundTiling = APNGUtility.ParseUint(chunkData, 1, ref offset); } }