/// <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 AbstractPngChunk FactoryFromId(string cid, ImageInfo info) { AbstractPngChunk chunk = null; if (factoryMap is null) { _ = InitFactory(); } if (IsKnown(cid)) { var t = factoryMap[cid]; if (t is null) { Console.Error.WriteLine("What?? " + cid); } var cons = t.GetConstructor(new Type[] { typeof(ImageInfo) }); var o = cons.Invoke(new object[] { info }); chunk = (AbstractPngChunk)o; } if (chunk is null) { chunk = new PngChunkUNKNOWN(cid, info); } return(chunk); }
/// <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(AbstractPngChunk chunk, int chunkGroup) { if (chunk is null) { throw new ArgumentNullException(nameof(chunk)); } chunk.ChunkGroup = chunkGroup; PngChunks.Add(chunk); }
/** * this should be called only for ancillary chunks and PLTE (groups 1 - 3 - 5) **/ private static bool ShouldWrite(AbstractPngChunk c, int currentGroup) { if (currentGroup == CHUNK_GROUP_2_PLTE) { return(c.Id.Equals(ChunkHelper.PLTE, System.StringComparison.Ordinal)); } if (currentGroup % 2 == 0) { throw new PngjOutputException("bad chunk group?"); } int minChunkGroup; int maxChunkGroup; if (c.MustGoBeforePLTE()) { minChunkGroup = maxChunkGroup = ChunksList.CHUNK_GROUP_1_AFTERIDHR; } else if (c.MustGoBeforeIDAT()) { maxChunkGroup = ChunksList.CHUNK_GROUP_3_AFTERPLTE; minChunkGroup = c.MustGoAfterPLTE() ? ChunksList.CHUNK_GROUP_3_AFTERPLTE : ChunksList.CHUNK_GROUP_1_AFTERIDHR; } else { maxChunkGroup = ChunksList.CHUNK_GROUP_5_AFTERIDAT; minChunkGroup = ChunksList.CHUNK_GROUP_1_AFTERIDHR; } var preferred = maxChunkGroup; if (c.Priority) { preferred = minChunkGroup; } if (ChunkHelper.IsUnknown(c) && c.ChunkGroup > 0) { preferred = c.ChunkGroup; } if (currentGroup == preferred) { return(true); } if (currentGroup > preferred && currentGroup <= maxChunkGroup) { return(true); } return(false); }
/// <summary>Queues the chunk at the writer</summary> /// <param name="chunk">Chunk, ready for write</param> /// <param name="lazyOverwrite">Ovewrite lazily equivalent chunks</param> /// <remarks>Warning: the overwriting applies to equivalent chunks, see <c>ChunkPredicateEquiv</c> /// and will only make sense for queued (not yet writen) chunks /// </remarks> public void QueueChunk(AbstractPngChunk chunk, bool lazyOverwrite) { var cl = getChunkListW(); if (ReadOnly) { throw new PngjException("cannot set chunk : readonly metadata"); } if (lazyOverwrite) { ChunkHelper.TrimList(cl.GetQueuedChunks(), new ChunkPredicateEquiv(chunk)); } cl.Queue(chunk); }
/// <summary> /// Decides if a chunk should be loaded, according to a ChunkLoadBehaviour /// </summary> /// <param name="id"></param> /// <param name="behav"></param> /// <returns></returns> public static bool ShouldLoad(string id, ChunkLoadBehaviour behav) { if (IsCritical(id)) { return(true); } var kwown = AbstractPngChunk.IsKnown(id); return(behav switch { ChunkLoadBehaviour.LOAD_CHUNK_ALWAYS => true, ChunkLoadBehaviour.LOAD_CHUNK_IF_SAFE => kwown || IsSafeToCopy(id), ChunkLoadBehaviour.LOAD_CHUNK_KNOWN => kwown, ChunkLoadBehaviour.LOAD_CHUNK_NEVER => false, _ => false,// should not reach here });
public override void CloneDataFromRead(AbstractPngChunk other) { CloneData((PngChunkSPLT)other); }
public override void CloneDataFromRead(AbstractPngChunk other) { // THIS SHOULD NOT BE CALLED IF ALREADY CLONED WITH COPY CONSTRUCTOR data = CloneData((PngChunkUNKNOWN)other); // not deep copy }
/// <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(AbstractPngChunk c) { return(queuedChunks.Remove(c)); }
/// <summary> /// Adds chunk to queue /// </summary> /// <remarks>Does not check for duplicated or anything</remarks> /// <param name="chunk"></param> /// <returns></returns> public bool Queue(AbstractPngChunk chunk) { queuedChunks.Add(chunk); return(true); }
/// <summary>Queues the chunk at the writer</summary> /// <param name="chunk">Chunk, ready for write</param> public void QueueChunk(AbstractPngChunk chunk) { QueueChunk(chunk, true); }
/// <summary> /// Finds all chunks "equivalent" to this one /// </summary> /// <param name="chunk"></param> /// <returns>Empty if nothing found</returns> public List <AbstractPngChunk> GetEquivalent(AbstractPngChunk chunk) { return(ChunkHelper.FilterList(PngChunks, new ChunkPredicateEquiv(chunk))); }
/// <summary> /// Override to make a copy (normally deep) from other chunk /// </summary> /// <param name="other"></param> public abstract void CloneDataFromRead(AbstractPngChunk other);
/// <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(AbstractPngChunk chunk) { return(chunk is PngChunkUNKNOWN); }