/// <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);
        }
Exemple #2
0
        /// <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);
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        /// <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
            });
Exemple #6
0
 public override void CloneDataFromRead(AbstractPngChunk other)
 {
     CloneData((PngChunkSPLT)other);
 }
Exemple #7
0
 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);
 }
Exemple #10
0
 /// <summary>Queues the chunk at the writer</summary>
 /// <param name="chunk">Chunk, ready for write</param>
 public void QueueChunk(AbstractPngChunk chunk)
 {
     QueueChunk(chunk, true);
 }
Exemple #11
0
 /// <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)));
 }
Exemple #12
0
 /// <summary>
 /// Override to make a copy (normally deep) from other chunk
 /// </summary>
 /// <param name="other"></param>
 public abstract void CloneDataFromRead(AbstractPngChunk other);
Exemple #13
0
 /// <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);
 }