コード例 #1
0
ファイル: HuffmanTable.cs プロジェクト: forestrf/AlantaMedia
        /// <summary>Figure F.16 - Reads the huffman code bit-by-bit.</summary>
        public JpegReadStatusInt Decode(JpegBinaryReader jpegStream)
        {
            int i         = 0;
            var readState = jpegStream.ReadBits(1);

            if (readState.Status != Status.Success)
            {
                return(readState);
            }
            short code = (short)readState.Result;

            while (code > maxcode[i])
            {
                i++;
                code    <<= 1;
                readState = jpegStream.ReadBits(1);
                if (readState.Status != Status.Success)
                {
                    return(readState);
                }
                code |= (short)readState.Result;
            }
            readState.Result = huffval[code + (valptr[i])];
            if (readState.Result < 0)
            {
                readState.Result = 256 + readState.Result;
            }
            readState.Status = Status.Success;
            return(readState);
        }
コード例 #2
0
        public JpegReadStatusInt DecodeACFirst(JpegBinaryReader stream, float[] zz)
        {
            if (stream.eobRun > 0)
            {
                stream.eobRun--;
                return(JpegReadStatusInt.GetSuccess());
            }

            for (int k = spectralStart; k <= spectralEnd; k++)
            {
                var status = ACTable.Decode(stream);
                if (status.Status != Status.Success)
                {
                    return(status);
                }
                int s = status.Result;
                int r = s >> 4;
                s &= 15;

                if (s != 0)
                {
                    k     += r;
                    status = stream.ReadBits(s);
                    if (status.Status != Status.Success)
                    {
                        return(status);
                    }
                    r     = status.Result;
                    s     = HuffmanTable.Extend(r, s);
                    zz[k] = s << successiveLow;
                }
                else
                {
                    if (r != 15)
                    {
                        stream.eobRun = 1 << r;

                        if (r != 0)
                        {
                            status = stream.ReadBits(r);
                            if (status.Status != Status.Success)
                            {
                                return(status);
                            }
                            stream.eobRun += status.Result;
                        }

                        stream.eobRun--;
                        break;
                    }

                    k += 15;
                }
            }
            return(JpegReadStatusInt.GetSuccess());
        }
コード例 #3
0
ファイル: JpegDecoder.cs プロジェクト: forestrf/AlantaMedia
        public JpegDecoder(Stream input)
        {
            jpegReader = new JpegBinaryReader(input);
            JpegReadStatusByte status;

            marker = (status = jpegReader.GetNextMarker()).Result;
            if (status.Status != Status.MarkerFound || status.Result != JpegMarker.SOI)
            {
                throw new Exception("Failed to find SOI marker.");
            }
        }
コード例 #4
0
        public JpegReadStatusInt DecodeDCRefine(JpegBinaryReader stream, float[] dest)
        {
            var status = stream.ReadBits(1);

            if (status.Status != Status.Success)
            {
                return(status);
            }
            if (status.Result == 1)
            {
                dest[0] = (int)dest[0] | (1 << successiveLow);
            }
            return(JpegReadStatusInt.GetSuccess());
        }
コード例 #5
0
        public JpegReadStatusInt DecodeBaseline(JpegBinaryReader stream, float[] dest)
        {
            float dc;
            var   status = decode_dc_coefficient(stream, out dc);

            if (status.Status != Status.Success)
            {
                return(status);
            }
            status = decode_ac_coefficients(stream, dest);
            if (status.Status == Status.Success)
            {
                dest[0] = dc;
            }
            return(status);
        }
コード例 #6
0
        /// <summary>
        /// Generated from text on F-22, F.2.2.1 - Huffman decoding of DC
        /// coefficients on ISO DIS 10918-1. Requirements and Guidelines.
        /// </summary>
        /// <param name="jpegStream">Stream that contains huffman bits</param>
        /// <param name="diff">The DC coefficient</param>
        /// <returns>The result of the read</returns>
        public JpegReadStatusInt decode_dc_coefficient(JpegBinaryReader jpegStream, out float diff)
        {
            diff = 0;
            var status = DCTable.Decode(jpegStream);

            if (status.Status != Status.Success)
            {
                return(status);
            }
            int t = status.Result;

            status = jpegStream.ReadBits(t);
            if (status.Status != Status.Success)
            {
                return(status);
            }
            diff       = HuffmanTable.Extend(status.Result, t);
            diff       = (previousDC + diff);
            previousDC = diff;
            return(status);
        }
コード例 #7
0
        public void Decode(byte[][][] rasterOutput)
        {
            // This assumes that the stream contains only a single frame.
            var       jpegReader = new JpegBinaryReader(input);
            JpegFrame frame      = context.JpegFrame;

            // Not relevant
            byte      marker        = JpegMarker.XFF;
            const int resetInterval = 255;

            frame.DecodeScan(FrameDefaults.NumberOfComponents, FrameDefaults.CompId, resetInterval, jpegReader, ref marker);

            // Only one frame, JPEG Non-Hierarchical Frame.
            // byte[][,] raster = Image.CreateRasterBuffer(frame.Width, frame.Height, frame.ComponentCount);

            IList <JpegComponent> components = frame.Scan.Components;

            // parse.Stop();

            for (int i = 0; i < components.Count; i++)
            {
                JpegComponent comp = components[i];

                // 1. Quantize
                // comp.QuantizationTable = qTables[comp.quant_id].Table;
                // Only the AAN needs this. The quantization step is built into the other IDCT implementations
                if (JpegConstants.SelectedIdct != IdctImplementation.AAN)
                {
                    comp.QuantizeData();
                }

                // 2. Run iDCT (expensive)
                // idct.Start();
                comp.IdctData();
                // idct.Stop();

                // 3. Scale the image and write the data to the raster.
                comp.WriteDataScaled(rasterOutput, i, BlockUpsamplingMode);
            }
        }
コード例 #8
0
        /// <summary>
        /// Generated from text on F-23, F.13 - Huffman decoded of AC coefficients
        /// on ISO DIS 10918-1. Requirements and Guidelines.
        /// </summary>
        internal JpegReadStatusInt decode_ac_coefficients(JpegBinaryReader jpegStream, float[] zz)
        {
            var status = new JpegReadStatusInt();

            for (int k = 1; k < 64; k++)
            {
                status = ACTable.Decode(jpegStream);
                if (status.Status != Status.Success)
                {
                    return(status);
                }
                int s = status.Result;
                int r = s >> 4;
                s &= 15;

                if (s != 0)
                {
                    k     += r;
                    status = jpegStream.ReadBits(s);
                    if (status.Status != Status.Success)
                    {
                        return(status);
                    }
                    s     = HuffmanTable.Extend(status.Result, s);
                    zz[k] = s;
                }
                else
                {
                    if (r != 15)
                    {
                        //throw new JPEGMarkerFoundException();
                        return(status);
                    }
                    k += 15;
                }
            }
            return(status);
        }
コード例 #9
0
        public JpegReadStatusInt DecodeDCFirst(JpegBinaryReader stream, float[] dest)
        {
            var status = DCTable.Decode(stream);

            if (status.Status != Status.Success)
            {
                return(status);                // We reached the end of the stream.
            }
            int s = status.Result;

            status = stream.ReadBits(s);
            if (status.Status != Status.Success)
            {
                return(status);
            }
            int r = status.Result;

            s          = HuffmanTable.Extend(r, s);
            s          = (int)previousDC + s;
            previousDC = s;

            dest[0] = s << successiveLow;
            return(status);
        }
コード例 #10
0
ファイル: JpegFrame.cs プロジェクト: forestrf/AlantaMedia
        public void DecodeScanBaseline(byte numberOfComponents, byte[] componentSelector, int resetInterval, JpegBinaryReader jpegReader, ref byte marker)
        {
            // Set the decode function for all the components
            for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
            {
                JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]);
                comp.Decode = comp.DecodeBaseline;
            }

            DecodeScan(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
        }
コード例 #11
0
ファイル: JpegFrame.cs プロジェクト: forestrf/AlantaMedia
        public bool DecodeScanProgressive(byte successiveApproximation, byte startSpectralSelection, byte endSpectralSelection,
                                          byte numberOfComponents, byte[] componentSelector, int resetInterval, JpegBinaryReader jpegReader, ref byte marker)
        {
            var successiveHigh = (byte)(successiveApproximation >> 4);
            var successiveLow  = (byte)(successiveApproximation & 0x0f);

            if ((startSpectralSelection > endSpectralSelection) || (endSpectralSelection > 63))
            {
                throw new Exception("Bad spectral selection.");
            }

            bool dcOnly         = startSpectralSelection == 0;
            bool refinementScan = (successiveHigh != 0);

            if (dcOnly)             // DC scan
            {
                if (endSpectralSelection != 0)
                {
                    throw new Exception("Bad spectral selection for DC only scan.");
                }
            }
            else             // AC scan
            {
                if (numberOfComponents > 1)
                {
                    throw new Exception("Too many components for AC scan!");
                }
            }

            // Set the decode function for all the components
            // TODO: set this for the scan and let the component figure it out
            for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
            {
                JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]);

                comp.successiveLow = successiveLow;

                if (dcOnly)
                {
                    if (refinementScan)                     // DC refine
                    {
                        comp.Decode = comp.DecodeDCRefine;
                    }
                    else                      //               DC first
                    {
                        comp.Decode = comp.DecodeDCFirst;
                    }
                }
                else
                {
                    comp.spectralStart = startSpectralSelection;
                    comp.spectralEnd   = endSpectralSelection;

                    if (refinementScan)                     // AC refine
                    {
                        comp.Decode = comp.DecodeACRefine;
                    }
                    else                      //               AC first
                    {
                        comp.Decode = comp.DecodeACFirst;
                    }
                }
            }

            DecodeScan(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
            return(true);
        }
コード例 #12
0
ファイル: JpegFrame.cs プロジェクト: forestrf/AlantaMedia
        public void DecodeScan(byte numberOfComponents, byte[] componentSelector, int resetInterval, JpegBinaryReader jpegReader, ref byte marker)
        {
            //TODO: not necessary
            jpegReader.eobRun = 0;

            int mcuIndex      = 0;
            int mcuTotalIndex = 0;

            // This loops through until a MarkerTagFound exception is
            // found, if the marker tag is a RST (Restart Marker) it
            // simply skips it and moves on this system does not handle
            // corrupt data streams very well, it could be improved by
            // handling misplaced restart markers.

            int h = 0, v = 0;
            int x = 0;

            long lastPosition = jpegReader.BaseStream.Position;

            foreach (JpegComponent component in Scan.Components)
            {
                component.Reset();
            }

            //TODO: replace this with a loop which knows how much data to expect
            while (true)
            {
                #region Inform caller of decode progress

                if (ProgressUpdateMethod != null)
                {
                    if (jpegReader.BaseStream.Position >= lastPosition + JpegDecoder.ProgressUpdateByteInterval)
                    {
                        lastPosition = jpegReader.BaseStream.Position;
                        ProgressUpdateMethod(lastPosition);
                    }
                }

                #endregion

                // Loop though capturing MCU, instruct each
                // component to read in its necessary count, for
                // scaling factors the components automatically
                // read in how much they need

                // Sec A.2.2 from CCITT Rec. T.81 (1992 E)
                bool interleaved = numberOfComponents != 1;

                if (!interleaved)
                {
                    #region Non-Interleaved (less common)
                    JpegComponent comp = Scan.GetComponentById(componentSelector[0]);
                    comp.SetBlock(mcuIndex);
                    var status = comp.DecodeMCU(jpegReader, h, v);
                    if (status.Status == Status.EOF)
                    {
                        return;
                    }
                    int mcusPerLine   = mcus_per_row(comp);
                    var blocksPerLine = (int)Math.Ceiling((double)Width / (8 * comp.factorH));

                    // TODO: Explain the non-interleaved scan ------
                    h++; x++;
                    if (h == comp.factorH)
                    {
                        h = 0; mcuIndex++;
                    }

                    if ((x % mcusPerLine) == 0)
                    {
                        x = 0;
                        v++;
                        if (v == comp.factorV)
                        {
                            if (h != 0)
                            {
                                mcuIndex++; h = 0;
                            }
                            v = 0;
                        }
                        else
                        {
                            mcuIndex -= blocksPerLine;
                            // we were mid-block
                            if (h != 0)
                            {
                                mcuIndex++; h = 0;
                            }
                        }
                    }

                    // -----------------------------------------------
                    #endregion
                }
                else                 // Components are interleaved
                {
                    #region Interleaved (more common)
                    for (int compIndex = 0; compIndex < numberOfComponents; compIndex++)
                    {
                        JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]);
                        comp.SetBlock(mcuTotalIndex);

                        for (int j = 0; j < comp.factorV; j++)
                        {
                            for (int i = 0; i < comp.factorH; i++)
                            {
                                // Decode the MCU
                                var status = comp.DecodeMCU(jpegReader, i, j);
                                if (status.Status == Status.EOF)
                                {
                                    return;
                                }
                                if (status.Status == Status.MarkerFound)
                                {
                                    // We've found a marker, see if the marker is a restart
                                    // marker or just the next marker in the stream. If
                                    // it's the next marker in the stream break out of the
                                    // while loop, if it's just a restart marker skip it
                                    marker = (byte)status.Result;

                                    // Handle JPEG Restart Markers, this is where the
                                    // count of MCU's per interval is compared with
                                    // the count actually obtained, if it's short then
                                    // pad on some MCU's ONLY for components that are
                                    // greater than one. Also restart the DC prediction
                                    // to zero.
                                    if (marker == JpegMarker.RST0 ||
                                        marker == JpegMarker.RST1 ||
                                        marker == JpegMarker.RST2 ||
                                        marker == JpegMarker.RST3 ||
                                        marker == JpegMarker.RST4 ||
                                        marker == JpegMarker.RST5 ||
                                        marker == JpegMarker.RST6 ||
                                        marker == JpegMarker.RST7)
                                    {
                                        for (int compIndex2 = 0; compIndex2 < numberOfComponents; compIndex2++)
                                        {
                                            JpegComponent comp2 = Scan.GetComponentById(componentSelector[compIndex]);
                                            if (compIndex2 > 1)
                                            {
                                                comp2.padMCU(mcuTotalIndex, resetInterval - mcuIndex);
                                            }
                                            comp2.resetInterval();
                                        }

                                        mcuTotalIndex += (resetInterval - mcuIndex);
                                        mcuIndex       = 0;
                                    }
                                    else
                                    {
                                        return;                                         // We're at the end of our scan, exit out.
                                    }
                                }
                            }
                        }
                    }

                    mcuIndex++;
                    mcuTotalIndex++;
                    #endregion
                }
            }
        }
コード例 #13
0
 public JpegReadStatusInt DecodeMCU(JpegBinaryReader jpegReader, int i, int j)
 {
     return(Decode(jpegReader, scanMCUs[i][j]));
 }
コード例 #14
0
        public JpegReadStatusInt DecodeACRefine(JpegBinaryReader stream, float[] dest)
        {
            int p1 = 1 << successiveLow;
            int m1 = (-1) << successiveLow;

            int k = spectralStart;

            if (stream.eobRun == 0)
            {
                for (; k <= spectralEnd; k++)
                {
                    #region Decode and check S

                    var status = ACTable.Decode(stream);
                    if (status.Status != Status.Success)
                    {
                        return(status);
                    }
                    int s = status.Result;
                    int r = s >> 4;
                    s &= 15;

                    if (s != 0)
                    {
                        if (s != 1)
                        {
                            throw new Exception("Decode Error");
                        }

                        status = stream.ReadBits(1);
                        if (status.Status != Status.Success)
                        {
                            return(status);
                        }
                        s = status.Result == 1 ? p1 : m1;
                    }
                    else
                    {
                        if (r != 15)
                        {
                            stream.eobRun = 1 << r;

                            if (r > 0)
                            {
                                status = stream.ReadBits(r);
                                if (status.Status != Status.Success)
                                {
                                    return(status);
                                }
                                stream.eobRun += status.Result;
                            }
                            break;
                        }
                    }                     // if (s != 0)

                    #endregion

                    // Apply the update
                    do
                    {
                        if (dest[k] != 0)
                        {
                            status = stream.ReadBits(1);
                            if (status.Status != Status.Success)
                            {
                                return(status);
                            }
                            if (status.Result == 1)
                            {
                                if (((int)dest[k] & p1) == 0)
                                {
                                    if (dest[k] >= 0)
                                    {
                                        dest[k] += p1;
                                    }
                                    else
                                    {
                                        dest[k] += m1;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (--r < 0)
                            {
                                break;
                            }
                        }

                        k++;
                    } while (k <= spectralEnd);

                    if ((s != 0) && k < 64)
                    {
                        dest[k] = s;
                    }
                }                 // for k = start ... end
            }
            if (stream.eobRun > 0)
            {
                for (; k <= spectralEnd; k++)
                {
                    if (dest[k] != 0)
                    {
                        var status = stream.ReadBits(1);
                        if (status.Status != Status.Success)
                        {
                            return(status);
                        }
                        if (status.Result == 1)
                        {
                            if (((int)dest[k] & p1) == 0)
                            {
                                if (dest[k] >= 0)
                                {
                                    dest[k] += p1;
                                }
                                else
                                {
                                    dest[k] += m1;
                                }
                            }
                        }
                    }
                }

                stream.eobRun--;
            }
            return(JpegReadStatusInt.GetSuccess());
        }