예제 #1
0
        /// <summary>
        /// Each thread creates its own list of ImageBlocks. This avoids locking
        /// but now we need to combine the lists into a single sorted list. Each
        /// thread's list is already sorted by offset.
        /// </summary>
        /// <param name="nThreads">Number of threads.</param>
        private void CollateList(int nThreads)
        {
            if (nThreads == 1)
            {
                ImageBlocks.AddRange(threadBlocks[0]);
                return;
            }
            // It's possible that we can have an image that overlaps with another
            // image found by separate threads. use the first image, which is
            // euqivalent to what would happen if we had a single thread.
            long prevEnd = -1;

            for (int n = 0; n < nThreads; n++)
            {
                for (int i = 0; i < threadBlocks[n].Count; i++)
                {
                    ImageBlock ib = threadBlocks[n][i];
                    if (ib.Offset > prevEnd)
                    {
                        ImageBlocks.Add(ib);
                        prevEnd = ib.Offset + ib.Length - 1;
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Given a block of memory that all or partially contains an image,
        /// reduce the memory to not contain the image.
        /// </summary>
        /// <param name="block">Block of memory</param>
        /// <param name="imageBlock">Image location and length in memory.</param>
        /// <returns>A list of new blocks that exclude the image.</returns>
        private static List <Block> RemoveImageBlock(Block block, ImageBlock imageBlock)
        {
            long blockStart = block.OffsetFile;
            long blockEnd   = blockStart + block.Length - 1;    // inclusive
            long imgStart   = imageBlock.Offset;
            long imgEnd     = imgStart + imageBlock.Length - 1; // inclusive

            if ((blockStart >= imgStart) && (blockEnd <= imgEnd))
            {
                // Simple case: block entirely within the image.
                return(new List <Block>());
            }
            List <Block> reduced     = new List <Block>();
            Block        blockBefore = null;
            Block        blockAfter  = null;

            if ((imgStart >= blockStart) && (imgEnd <= blockEnd))
            {
                // Image entirely within the block. Can have memory before and
                // after the image. May need to split memory block into two
                // blocks.
                int len = 0;
                if (blockStart < imgStart)
                {
                    // Have memory before.
                    len = (int)(imgStart - blockStart);
                    byte[] data = null;
                    if (block.Bytes != null)
                    {
                        data = new byte[len];
                        Array.Copy(block.Bytes, 0, data, 0, len);
                    }
                    blockBefore = new Block {
                        OffsetFile = blockStart, Length = len, Bytes = data
                    };
                }
                // Have memory after.
                if (imgEnd < blockEnd)
                {
                    long fileOffset  = imgEnd + 1;
                    int  arrayOffset = len + imageBlock.Length;
                    len = (int)(blockEnd - imgEnd);
                    byte[] data = null;
                    if (block.Bytes != null)
                    {
                        data = new byte[len];
                        Array.Copy(block.Bytes, arrayOffset, data, 0, len);
                    }
                    blockAfter = new Block {
                        OffsetFile = fileOffset, Length = len, Bytes = data
                    };
                }
            }
            else if (blockStart < imgStart)
            {
                // Block overlaps the image at the higher end of the memory.
                int    len  = (int)(imgStart - blockStart);
                byte[] data = null;
                if (block.Bytes != null)
                {
                    data = new byte[len];
                    Array.Copy(block.Bytes, 0, data, 0, len);
                }
                blockBefore = new Block {
                    OffsetFile = blockStart, Length = len, Bytes = data
                };
            }
            else if (imgEnd < blockEnd)
            {
                // Block overlaps the image at the lower end of the memory.
                long   fileOffset = imgEnd + 1;
                int    len        = (int)(blockEnd - imgEnd);
                byte[] data       = null;
                if (block.Bytes != null)
                {
                    data = new byte[len];
                    int arrayOffset = block.Length - len;
                    Array.Copy(block.Bytes, arrayOffset, data, 0, len);
                }
                blockAfter = new Block {
                    OffsetFile = fileOffset, Length = len, Bytes = data
                };
            }
            if (blockBefore != null)
            {
                reduced.Add(blockBefore);
            }
            if (blockAfter != null)
            {
                reduced.Add(blockAfter);
            }
            return(reduced);
        }
예제 #3
0
 /// <summary>
 /// Called by a thread when it discovers an image. Adds the image to a list.
 /// </summary>
 /// <param name="block">ImageBlock object represeting the located image.</param>
 /// <param name="id">Xero-based index identifying the thread.</param>
 public void AddBlock(ImageBlock block, int id)
 {
     threadBlocks[id].Add(block);
 }