Example #1
0
        /// <summary>
        /// Initializes <see cref="SpectralBlocks"/>
        /// </summary>
        /// <param name="memoryManager">The <see cref="MemoryManager"/> to use for buffer allocations.</param>
        /// <param name="decoder">The <see cref="GolangJpegDecoderCore"/> instance</param>
        public void InitializeDerivedData(MemoryManager memoryManager, GolangJpegDecoderCore decoder)
        {
            // For 4-component images (either CMYK or YCbCrK), we only support two
            // hv vectors: [0x11 0x11 0x11 0x11] and [0x22 0x11 0x11 0x22].
            // Theoretically, 4-component JPEG images could mix and match hv values
            // but in practice, those two combinations are the only ones in use,
            // and it simplifies the applyBlack code below if we can assume that:
            // - for CMYK, the C and K channels have full samples, and if the M
            // and Y channels subsample, they subsample both horizontally and
            // vertically.
            // - for YCbCrK, the Y and K channels have full samples.
            this.SizeInBlocks = decoder.ImageSizeInMCU.MultiplyBy(this.SamplingFactors);

            if (this.Index == 0 || this.Index == 3)
            {
                this.SubSamplingDivisors = new Size(1, 1);
            }
            else
            {
                GolangComponent c0 = decoder.Components[0];
                this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors);
            }

            this.SpectralBlocks = memoryManager.Allocate2D <Block8x8>(this.SizeInBlocks.Width, this.SizeInBlocks.Height, true);
        }
        private void DecodeBlocksAtMcuIndex(GolangJpegDecoderCore decoder, int mx, int my)
        {
            for (int scanIndex = 0; scanIndex < this.componentScanCount; scanIndex++)
            {
                this.ComponentIndex = this.pointers.ComponentScan[scanIndex].ComponentIndex;
                GolangComponent component = decoder.Components[this.ComponentIndex];

                this.hi = component.HorizontalSamplingFactor;
                int vi = component.VerticalSamplingFactor;

                for (int j = 0; j < this.hi * vi; j++)
                {
                    if (this.componentScanCount != 1)
                    {
                        this.bx = (this.hi * mx) + (j % this.hi);
                        this.by = (vi * my) + (j / this.hi);
                    }
                    else
                    {
                        int q = decoder.MCUCountX * this.hi;
                        this.bx = this.blockCounter % q;
                        this.by = this.blockCounter / q;
                        this.blockCounter++;
                        if (this.bx * 8 >= decoder.ImageWidth || this.by * 8 >= decoder.ImageHeight)
                        {
                            continue;
                        }
                    }

                    // Find the block at (bx,by) in the component's buffer:
                    ref Block8x8 blockRefOnHeap = ref component.GetBlockReference(this.bx, this.by);

                    // Copy block to stack
                    this.data.Block = blockRefOnHeap;

                    if (!decoder.InputProcessor.ReachedEOF)
                    {
                        this.DecodeBlock(decoder, scanIndex);
                    }

                    // Store the result block:
                    blockRefOnHeap = this.data.Block;
                }
            }