/** * this should be called only for ancillary chunks and PLTE (groups 1 - 3 - 5) **/ private static bool ShouldWrite(PngChunk c, int currentGroup) { if (currentGroup == CHUNK_GROUP_2_PLTE) { return(c.Id.Equals(ChunkHelper.PLTE)); } if (currentGroup % 2 == 0) { throw new PngjOutputException("bad chunk group?"); } int minChunkGroup, maxChunkGroup; if (c.MustGoBeforePLTE()) { minChunkGroup = maxChunkGroup = CHUNK_GROUP_1_AFTERIDHR; } else if (c.MustGoBeforeIDAT()) { maxChunkGroup = CHUNK_GROUP_3_AFTERPLTE; minChunkGroup = c.MustGoAfterPLTE() ? CHUNK_GROUP_3_AFTERPLTE : CHUNK_GROUP_1_AFTERIDHR; } else { maxChunkGroup = CHUNK_GROUP_5_AFTERIDAT; minChunkGroup = CHUNK_GROUP_1_AFTERIDHR; } int preferred = maxChunkGroup; if (c.Priority) { preferred = minChunkGroup; } if (currentGroup == preferred) { return(true); } if (currentGroup > preferred && currentGroup <= maxChunkGroup) { return(true); } return(false); }
/// <summary> Decides if a chunk should be loaded, according to a ChunkLoadBehaviour </summary> public static bool ShouldLoad(string id, ChunkLoadBehaviour behav) { if (IsCritical(id)) { return(true); } bool kwown = PngChunk.IsKnown(id); switch (behav) { case ChunkLoadBehaviour.LOAD_CHUNK_ALWAYS: return(true); case ChunkLoadBehaviour.LOAD_CHUNK_IF_SAFE: return(kwown || IsSafeToCopy(id)); case ChunkLoadBehaviour.LOAD_CHUNK_KNOWN: return(kwown); case ChunkLoadBehaviour.LOAD_CHUNK_NEVER: return(false); default: return(false); // should not reach here } }
/// <summary> Creates one new blank chunk of the corresponding type, according to factoryMap (PngChunkUNKNOWN if not known) </summary> /// <param name="cid">Chunk Id</param> internal static PngChunk FactoryFromId(string cid, ImageInfo info) { PngChunk chunk = null; if (IsKnown(cid)) { System.Type t = factoryMap[cid]; if (t == null) { UnityEngine.Debug.Log($"What?? {cid}"); } System.Reflection.ConstructorInfo cons = t.GetConstructor(new System.Type[] { typeof(ImageInfo) }); object o = cons.Invoke(new object[] { info }); chunk = (PngChunk)o; } if (chunk == null) { chunk = new PngChunkUNKNOWN(cid, info); } return(chunk); }
/// <summary> /// Creates one new blank chunk of the corresponding type, according to factoryMap (PngChunkUNKNOWN if not known) /// </summary> /// <param name="cid">Chunk Id</param> /// <param name="info"></param> /// <returns></returns> internal static PngChunk FactoryFromId(String cid, ImageInfo info) { PngChunk chunk = null; if (factoryMap == null) { initFactory(); } if (isKnown(cid)) { Type t = factoryMap[cid]; if (t == null) { Console.Error.WriteLine("What?? " + cid); } System.Reflection.ConstructorInfo cons = t.GetConstructor(new Type[] { typeof(ImageInfo) }); object o = cons.Invoke(new object[] { info }); chunk = (PngChunk)o; } return(chunk); }
/// <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); } // unknown chunks that allow multiple? consider they don't match return(false); }
/// <summary> /// Finds all chunks "equivalent" to this one /// </summary> /// <param name="chunk"></param> /// <returns>Empty if nothing found</returns> public List <PngChunk> GetEquivalent(PngChunk chunk) { return(ChunkHelper.FilterList(chunks, new ChunkPredicateEquiv(chunk))); }
public override void CloneDataFromRead(PngChunk other) { gamma = ((PngChunkGAMA)other).gamma; }
/// <summary> ///Remove Chunk: only from queued /// </summary> /// <remarks> /// WARNING: this depends on chunk.Equals() implementation, which is straightforward for SingleChunks. For /// MultipleChunks, it will normally check for reference equality! /// </remarks> /// <param name="c"></param> /// <returns></returns> public bool RemoveChunk(PngChunk c) { return(queuedChunks.Remove(c)); }
public override void CloneDataFromRead(PngChunk other) { }
/// <summary>Queues the chunk at the writer</summary> /// <param name="chunk">Chunk, ready for write</param> public void QueueChunk(PngChunk chunk) => QueueChunk(chunk, true);
/// <summary> Remove Chunk: only from queued </summary> /// <remarks> /// WARNING: this depends on chunk.Equals() implementation, which is straightforward for SingleChunks. For /// MultipleChunks, it will normally check for reference equality! /// </remarks> public bool RemoveChunk(PngChunk chunk) => queuedChunks.Remove(chunk);
public override void CloneDataFromRead(PngChunk other) { PngChunkSTER otherx = (PngChunkSTER)other; this.Mode = otherx.Mode; }
public static bool IsSafeToCopy(string id) => !char.IsUpper(id[3]); // safe to copy? // fourth letter is lower case /// <summary> We consider a chunk as "unknown" if our chunk factory (even when it has been augmented by client code) doesn't recognize it </summary> public static bool IsUnknown(PngChunk chunk) => chunk is PngChunkUNKNOWN;
public static bool IsText(PngChunk c) => c is PngChunkTextVar;
/// <summary> /// Adds chunk in next position. This is used only by the pngReader /// </summary> /// <param name="chunk"></param> /// <param name="chunkGroup"></param> public void AppendReadChunk(PngChunk chunk, int chunkGroup) { chunk.ChunkGroup = chunkGroup; chunks.Add(chunk); }
public bool Matches(PngChunk c) { return(c.Id.Equals(id)); }
/// <summary> /// Override to make a copy (normally deep) from other chunk /// </summary> /// <param name="other"></param> public abstract void CloneDataFromRead(PngChunk other);
public override void CloneDataFromRead(PngChunk other) { PngChunkSRGB otherx = (PngChunkSRGB)other; Intent = otherx.Intent; }
/// <summary> /// We consider a chunk as "unknown" if our chunk factory (even when it has been augmented by client code) doesn't recognize it /// </summary> /// <param name="chunk"></param> /// <returns></returns> public static bool IsUnknown(PngChunk chunk) { return(chunk is PngChunkUNKNOWN); }
// ///// high level utility methods follow //////////// // //////////// DPI /// <summary> /// Returns physical resolution, in DPI, in both coordinates /// </summary> /// <returns>[dpix,dpiy], -1 if not set or unknown dimensions</returns> public double[] GetDpi() { PngChunk c = chunkList.GetById1(ChunkHelper.pHYs, true); return(c != null ? ((PngChunkPHYS)c).GetAsDpi2() : new double[] { -1, -1 }); }
public static bool IsText(PngChunk c) { return(c is PngChunkTextVar); }
/// <summary> /// Creates predicate based of reference chunk /// </summary> /// <param name="chunk"></param> public ChunkPredicateEquiv(PngChunk chunk) { this.chunk = chunk; }
/// <summary> /// Check for match /// </summary> /// <param name="c"></param> /// <returns></returns> public bool Matches(PngChunk c) { return(ChunkHelper.Equivalent(c, chunk)); }
/// <summary> /// Adds chunk to queue /// </summary> /// <remarks>Does not check for duplicated or anything</remarks> /// <param name="chunk"></param> /// <returns></returns> public bool Queue(PngChunk chunk) { queuedChunks.Add(chunk); return(true); }
public sealed override void CloneDataFromRead(PngChunk other) { throw new PngjException("Non supported for a skipped chunk"); }