internal int writeChunks(Stream os, int currentGroup) { List <int> written = new List <int>(); for (int i = 0; i < queuedChunks.Count; i++) { PngChunk c = queuedChunks[i]; if (!shouldWrite(c, currentGroup)) { continue; } if (ChunkHelper.IsCritical(c.Id) && !c.Id.Equals(ChunkHelper.PLTE)) { throw new PngjOutputException("bad chunk queued: " + c); } if (alreadyWrittenKeys.ContainsKey(c.Id) && !c.AllowsMultiple()) { throw new PngjOutputException("duplicated chunk does not allow multiple: " + c); } c.write(os); chunks.Add(c); alreadyWrittenKeys[c.Id] = alreadyWrittenKeys.ContainsKey(c.Id) ? alreadyWrittenKeys[c.Id] + 1 : 1; written.Add(i); c.ChunkGroup = currentGroup; } for (int k = written.Count - 1; k >= 0; k--) { queuedChunks.RemoveAt(written[k]); } return(written.Count); }
/// <summary> /// Ad-hoc criteria for 'equivalent' chunks. /// </summary> /// <remarks> /// Two chunks are equivalent if they have the same Id AND either: /// 1. they are Single /// 2. both are textual and have the same key /// 3. both are SPLT and have the same palette name /// Bear in mind that this is an ad-hoc, non-standard, nor required (nor wrong) /// criterion. Use it only if you find it useful. Notice that PNG allows to have /// repeated textual keys with same keys. /// </remarks> /// <param name="c1">Chunk1</param> /// <param name="c2">Chunk1</param> /// <returns>true if equivalent</returns> public static bool Equivalent(PngChunk c1, PngChunk c2) { if (c1 == c2) { return(true); } if (c1 == null || c2 == null || !c1.Id.Equals(c2.Id)) { return(false); } // same id if (c1.GetType() != c2.GetType()) { return(false); // should not happen } if (!c2.AllowsMultiple()) { return(true); } if (c1 is PngChunkTextVar) { return(((PngChunkTextVar)c1).GetKey().Equals(((PngChunkTextVar)c2).GetKey())); } if (c1 is PngChunkSPLT) { return(((PngChunkSPLT)c1).PalName.Equals(((PngChunkSPLT)c2).PalName)); } // unknown chunks that allow multiple? consider they don't match return(false); }
public static bool Equivalent(PngChunk c1, PngChunk c2) { if (c1 == c2) { return(true); } if (c1 == null || c2 == null || !c1.Id.Equals(c2.Id)) { return(false); } if (c1.GetType() != c2.GetType()) { return(false); } if (!c2.AllowsMultiple()) { return(true); } if (c1 is PngChunkTextVar) { return(((PngChunkTextVar)c1).GetKey().Equals(((PngChunkTextVar)c2).GetKey())); } if (c1 is PngChunkSPLT) { return(((PngChunkSPLT)c1).PalName.Equals(((PngChunkSPLT)c2).PalName)); } return(false); }
internal int writeChunks(Stream os, int currentGroup) { List <int> list = new List <int>(); for (int i = 0; i < queuedChunks.Count; i++) { PngChunk pngChunk = queuedChunks[i]; if (shouldWrite(pngChunk, currentGroup)) { if (ChunkHelper.IsCritical(pngChunk.Id) && !pngChunk.Id.Equals("PLTE")) { throw new PngjOutputException("bad chunk queued: " + pngChunk?.ToString()); } if (alreadyWrittenKeys.ContainsKey(pngChunk.Id) && !pngChunk.AllowsMultiple()) { throw new PngjOutputException("duplicated chunk does not allow multiple: " + pngChunk?.ToString()); } pngChunk.write(os); chunks.Add(pngChunk); alreadyWrittenKeys[pngChunk.Id] = ((!alreadyWrittenKeys.ContainsKey(pngChunk.Id)) ? 1 : (alreadyWrittenKeys[pngChunk.Id] + 1)); list.Add(i); pngChunk.ChunkGroup = currentGroup; } } for (int num = list.Count - 1; num >= 0; num--) { queuedChunks.RemoveAt(list[num]); } return(list.Count); }