Exemplo n.º 1
0
        public void AddComponent(byte id, byte factorHorizontal, byte factorVertical, byte quantizationID, byte colorMode)
        {
            JpegComponent item = new JpegComponent(this, id, factorHorizontal, factorVertical, quantizationID, colorMode);

            components.Add(item);
            maxH = components.Max((JpegComponent x) => x.factorH);
            maxV = components.Max((JpegComponent x) => x.factorV);
        }
Exemplo n.º 2
0
 public void DecodeScanBaseline(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
 {
     for (int i = 0; i < numberOfComponents; i++)
     {
         JpegComponent componentById = Scan.GetComponentById(componentSelector[i]);
         componentById.Decode = componentById.DecodeBaseline;
     }
     DecodeScan(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
 }
Exemplo n.º 3
0
 public void AddComponent(byte id, byte factorHorizontal, byte factorVertical, byte quantizationID, byte colorMode)
 {
     JpegComponent item = new JpegComponent(this, id, factorHorizontal, factorVertical, quantizationID, colorMode);
     this.components.Add(item);
     this.maxH = this.components.Max<JpegComponent, byte>(delegate (JpegComponent x) {
         return x.factorH;
     });
     this.maxV = this.components.Max<JpegComponent, byte>(delegate (JpegComponent x) {
         return x.factorV;
     });
 }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        //private void DecodeScan(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
        //{
        //    jpegReader.eob_run = 0;
        //    int idx = 0;
        //    int num2 = 0;
        //    int i = 0;
        //    int j = 0;
        //    int num5 = 0;
        //    long position = jpegReader.BaseStream.Position;
        //    while (true)
        //    {
        //        JpegComponent componentById;
        //        int num9;
        //        if ((this.ProgressUpdateMethod != null) && (jpegReader.BaseStream.Position >= (position + JpegDecoder.ProgressUpdateByteInterval)))
        //        {
        //            position = jpegReader.BaseStream.Position;
        //            this.ProgressUpdateMethod(position);
        //        }
        //        try
        //        {
        //            if (numberOfComponents == 1)
        //            {
        //                componentById = this.Scan.GetComponentById(componentSelector[0]);
        //                componentById.SetBlock(idx);
        //                componentById.DecodeMCU(jpegReader, i, j);
        //                int num7 = this.mcus_per_row(componentById);
        //                int num8 = (int) Math.Ceiling(((double) this.Width) / ((double) (8 * componentById.factorH)));
        //                i++;
        //                num5++;
        //                if (i == componentById.factorH)
        //                {
        //                    i = 0;
        //                    idx++;
        //                }
        //                if ((num5 % num7) == 0)
        //                {
        //                    num5 = 0;
        //                    j++;
        //                    if (j == componentById.factorV)
        //                    {
        //                        if (i != 0)
        //                        {
        //                            idx++;
        //                            i = 0;
        //                        }
        //                        j = 0;
        //                    }
        //                    else
        //                    {
        //                        idx -= num8;
        //                        if (i != 0)
        //                        {
        //                            idx++;
        //                            i = 0;
        //                        }
        //                    }
        //                }
        //            }
        //            else
        //            {
        //                num9 = 0;
        //                while (num9 < numberOfComponents)
        //                {
        //                    componentById = this.Scan.GetComponentById(componentSelector[num9]);
        //                    componentById.SetBlock(num2);
        //                    for (int k = 0; k < componentById.factorV; k++)
        //                    {
        //                        for (int m = 0; m < componentById.factorH; m++)
        //                        {
        //                            componentById.DecodeMCU(jpegReader, m, k);
        //                        }
        //                    }
        //                    num9++;
        //                }
        //                idx++;
        //                num2++;
        //            }
        //        }
        //        catch (JPEGMarkerFoundException exception)
        //        {
        //            marker = exception.Marker;
        //            if (((((marker != 0xd0) && (marker != 0xd1)) && ((marker != 210) && (marker != 0xd3))) && (((marker != 0xd4) && (marker != 0xd5)) && (marker != 0xd6))) && (marker != 0xd7))
        //            {
        //                return;
        //            }
        //            for (num9 = 0; num9 < numberOfComponents; num9++)
        //            {
        //                componentById = this.Scan.GetComponentById(componentSelector[num9]);
        //                if (num9 > 1)
        //                {
        //                    componentById.padMCU(num2, resetInterval - idx);
        //                }
        //                componentById.resetInterval();
        //            }
        //            num2 += resetInterval - idx;
        //            idx = 0;
        //        }
        //    }
        //}

        //public void DecodeScanBaseline(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
        //{
        //    for (int i = 0; i < numberOfComponents; i++)
        //    {
        //        JpegComponent componentById = this.Scan.GetComponentById(componentSelector[i]);
        //        componentById.Decode = new JpegComponent.DecodeFunction(componentById.DecodeBaseline);
        //    }
        //    this.DecodeScan(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
        //}

        public void DecodeScanProgressive(byte successiveApproximation, byte startSpectralSelection, byte endSpectralSelection, byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
        {
            byte num  = (byte)(successiveApproximation >> 4);
            byte num2 = (byte)(successiveApproximation & 15);

            if ((startSpectralSelection > endSpectralSelection) || (endSpectralSelection > 0x3f))
            {
                throw new Exception("Bad spectral selection.");
            }
            bool flag  = startSpectralSelection == 0;
            bool flag2 = num != 0;

            if (flag)
            {
                if (endSpectralSelection != 0)
                {
                    throw new Exception("Bad spectral selection for DC only scan.");
                }
            }
            else if (numberOfComponents > 1)
            {
                throw new Exception("Too many components for AC scan!");
            }
            for (int i = 0; i < numberOfComponents; i++)
            {
                JpegComponent componentById = this.Scan.GetComponentById(componentSelector[i]);
                componentById.successiveLow = num2;
                if (flag)
                {
                    if (flag2)
                    {
                        componentById.Decode = new JpegComponent.DecodeFunction(componentById.DecodeDCRefine);
                    }
                    else
                    {
                        componentById.Decode = new JpegComponent.DecodeFunction(componentById.DecodeDCFirst);
                    }
                }
                else
                {
                    componentById.spectralStart = startSpectralSelection;
                    componentById.spectralEnd   = endSpectralSelection;
                    if (flag2)
                    {
                        componentById.Decode = new JpegComponent.DecodeFunction(componentById.DecodeACRefine);
                    }
                    else
                    {
                        componentById.Decode = new JpegComponent.DecodeFunction(componentById.DecodeACFirst);
                    }
                }
            }
            //   this.DecodeScan(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
        }
Exemplo n.º 6
0
        public void AddComponent(byte id, byte factorHorizontal, byte factorVertical,
                                 byte quantizationID, byte colorMode)
        {
            JpegComponent component = new JpegComponent(this,
                                                        id, factorHorizontal, factorVertical, quantizationID, colorMode);

            components.Add(component);

            // Defined in Annex A
            maxH = components.Max(x => x.factorH);
            maxV = components.Max(x => x.factorV);
        }
Exemplo n.º 7
0
        public void AddComponent(byte id, byte factorHorizontal, byte factorVertical, byte quantizationID, byte colorMode)
        {
            JpegComponent item = new JpegComponent(this, id, factorHorizontal, factorVertical, quantizationID, colorMode);

            this.components.Add(item);
            this.maxH = this.components.Max <JpegComponent, byte>(delegate(JpegComponent x) {
                return(x.factorH);
            });
            this.maxV = this.components.Max <JpegComponent, byte>(delegate(JpegComponent x) {
                return(x.factorV);
            });
        }
Exemplo n.º 8
0
        public void AddComponent(byte id, byte factorHorizontal, byte factorVertical,
                                 byte quantizationID, byte colorMode)
        {
            JpegComponent component = new JpegComponent( this,
                id, factorHorizontal, factorVertical, quantizationID, colorMode);

            components.Add(component);

            // Defined in Annex A
            maxH = components.Max(x => x.factorH);
            maxV = components.Max(x => x.factorV);
        }
Exemplo n.º 9
0
        public void DecodeScanProgressive(byte successiveApproximation, byte startSpectralSelection, byte endSpectralSelection, byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
        {
            byte b             = (byte)(successiveApproximation >> 4);
            byte successiveLow = (byte)(successiveApproximation & 0xF);

            if (startSpectralSelection > endSpectralSelection || endSpectralSelection > 63)
            {
                throw new Exception("Bad spectral selection.");
            }
            bool flag  = startSpectralSelection == 0;
            bool flag2 = b != 0;

            if (flag)
            {
                if (endSpectralSelection != 0)
                {
                    throw new Exception("Bad spectral selection for DC only scan.");
                }
            }
            else if (numberOfComponents > 1)
            {
                throw new Exception("Too many components for AC scan!");
            }
            for (int i = 0; i < numberOfComponents; i++)
            {
                JpegComponent componentById = Scan.GetComponentById(componentSelector[i]);
                componentById.successiveLow = successiveLow;
                if (flag)
                {
                    if (flag2)
                    {
                        componentById.Decode = componentById.DecodeDCRefine;
                    }
                    else
                    {
                        componentById.Decode = componentById.DecodeDCFirst;
                    }
                    continue;
                }
                componentById.spectralStart = startSpectralSelection;
                componentById.spectralEnd   = endSpectralSelection;
                if (flag2)
                {
                    componentById.Decode = componentById.DecodeACRefine;
                }
                else
                {
                    componentById.Decode = componentById.DecodeACFirst;
                }
            }
            DecodeScan(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
        }
Exemplo n.º 10
0
        public void setHuffmanTables(byte componentID, JpegHuffmanTable ACTable, JpegHuffmanTable DCTable)
        {
            JpegComponent comp = Scan.GetComponentById(componentID);

            if (DCTable != null)
            {
                comp.setDCTable(DCTable);
            }
            if (ACTable != null)
            {
                comp.setACTable(ACTable);
            }
        }
Exemplo n.º 11
0
        public DecodedJpeg Decode()
        {
            // The frames in this jpeg are loaded into a list. There is
            // usually just one frame except in heirarchial progression where
            // there are multiple frames.
            JPEGFrame frame = null;

            // The restart interval defines how many MCU's we should have
            // between the 8-modulo restart marker. The restart markers allow
            // us to tell whether or not our decoding process is working
            // correctly, also if there is corruption in the image we can
            // recover with these restart intervals. (See RSTm DRI).
            int resetInterval = 0;

            bool haveMarker = false;
            bool foundJFIF  = false;

            List <JpegHeader> headers = new List <JpegHeader>();

            // Loop through until there are no more markers to read in, at
            // that point everything is loaded into the jpegFrames array and
            // can be processed.
            while (true)
            {
                #region Switch over marker types
                switch (marker)
                {
                case JPEGMarker.APP0:
                // APP1 is used for EXIF data
                case JPEGMarker.APP1:
                // Seldomly, APP2 gets used for extended EXIF, too
                case JPEGMarker.APP2:
                case JPEGMarker.APP3:
                case JPEGMarker.APP4:
                case JPEGMarker.APP5:
                case JPEGMarker.APP6:
                case JPEGMarker.APP7:
                case JPEGMarker.APP8:
                case JPEGMarker.APP9:
                case JPEGMarker.APP10:
                case JPEGMarker.APP11:
                case JPEGMarker.APP12:
                case JPEGMarker.APP13:
                case JPEGMarker.APP14:
                case JPEGMarker.APP15:
                // COM: Comment
                case JPEGMarker.COM:

                    // Debug.WriteLine(string.Format("Extracting Header, Type={0:X}", marker));

                    JpegHeader header = ExtractHeader();

                    #region Check explicitly for Exif Data

                    if (header.Marker == JPEGMarker.APP1 && header.Data.Length >= 6)
                    {
                        byte[] d = header.Data;

                        if (d[0] == 'E' &&
                            d[1] == 'x' &&
                            d[2] == 'i' &&
                            d[3] == 'f' &&
                            d[4] == 0 &&
                            d[5] == 0)
                        {
                            // Exif.  Do something?
                        }
                    }

                    #endregion

                    #region Check for Adobe header

                    if (header.Data.Length >= 5 && header.Marker == JPEGMarker.APP14)
                    {
                        string asText = UTF8Encoding.UTF8.GetString(header.Data, 0, 5);
                        if (asText == "Adobe")
                        {
                            // ADOBE HEADER.  Do anything?
                        }
                    }

                    #endregion

                    headers.Add(header);

                    if (!foundJFIF && marker == JPEGMarker.APP0)
                    {
                        foundJFIF = TryParseJFIF(header.Data);

                        if (foundJFIF)     // Found JFIF... do JFIF extension follow?
                        {
                            header.IsJFIF = true;
                            marker        = jpegReader.GetNextMarker();

                            // Yes, they do.
                            if (marker == JPEGMarker.APP0)
                            {
                                header = ExtractHeader();
                                headers.Add(header);
                            }
                            else     // No.  Delay processing this one.
                            {
                                haveMarker = true;
                            }
                        }
                    }

                    break;

                case JPEGMarker.SOF0:
                case JPEGMarker.SOF2:

                    // SOFn Start of Frame Marker, Baseline DCT - This is the start
                    // of the frame header that defines certain variables that will
                    // be carried out through the rest of the encoding. Multiple
                    // frames are used in a hierarchical system, however most JPEG's
                    // only contain a single frame.

                    // Progressive or baseline?
                    progressive = marker == JPEGMarker.SOF2;

                    jpegFrames.Add(new JPEGFrame());
                    frame = (JPEGFrame)jpegFrames[jpegFrames.Count - 1];
                    frame.ProgressUpdateMethod = new Action <long>(UpdateStreamProgress);

                    // Skip the frame length.
                    jpegReader.ReadShort();
                    // Bits percision, either 8 or 12.
                    frame.setPrecision(jpegReader.ReadByte());
                    // Scan lines (height)
                    frame.ScanLines = jpegReader.ReadShort();
                    // Scan samples per line (width)
                    frame.SamplesPerLine = jpegReader.ReadShort();
                    // Number of Color Components (channels).
                    frame.ComponentCount = jpegReader.ReadByte();

                    DecodeProgress.Height    = frame.Height;
                    DecodeProgress.Width     = frame.Width;
                    DecodeProgress.SizeReady = true;

                    if (DecodeProgressChanged != null)
                    {
                        DecodeProgressChanged(this, DecodeProgress);
                    }

                    // Add all of the necessary components to the frame.
                    for (int i = 0; i < frame.ComponentCount; i++)
                    {
                        byte compId        = jpegReader.ReadByte();
                        byte sampleFactors = jpegReader.ReadByte();
                        byte qTableId      = jpegReader.ReadByte();

                        byte sampleHFactor = (byte)(sampleFactors >> 4);
                        byte sampleVFactor = (byte)(sampleFactors & 0x0f);

                        frame.AddComponent(compId, sampleHFactor, sampleVFactor, qTableId);
                    }
                    break;

                case JPEGMarker.DHT:

                    // DHT non-SOF Marker - Huffman Table is required for decoding
                    // the JPEG stream, when we receive a marker we load in first
                    // the table length (16 bits), the table class (4 bits), table
                    // identifier (4 bits), then we load in 16 bytes and each byte
                    // represents the count of bytes to load in for each of the 16
                    // bytes. We load this into an array to use later and move on 4
                    // huffman tables can only be used in an image.
                    int huffmanLength = (jpegReader.ReadShort() - 2);

                    // Keep looping until we are out of length.
                    int index = huffmanLength;

                    // Multiple tables may be defined within a DHT marker. This
                    // will keep reading until there are no tables left, most
                    // of the time there are just one tables.
                    while (index > 0)
                    {
                        // Read the identifier information and class
                        // information about the Huffman table, then read the
                        // 16 byte codelength in and read in the Huffman values
                        // and put it into table info.
                        byte    huffmanInfo  = jpegReader.ReadByte();
                        byte    tableClass   = (byte)(huffmanInfo >> 4);
                        byte    huffmanIndex = (byte)(huffmanInfo & 0x0f);
                        short[] codeLength   = new short[16];

                        for (int i = 0; i < codeLength.Length; i++)
                        {
                            codeLength[i] = jpegReader.ReadByte();
                        }

                        int huffmanValueLen = 0;
                        for (int i = 0; i < 16; i++)
                        {
                            huffmanValueLen += codeLength[i];
                        }
                        index -= (huffmanValueLen + 17);

                        short[] huffmanVal = new short[huffmanValueLen];
                        for (int i = 0; i < huffmanVal.Length; i++)
                        {
                            huffmanVal[i] = jpegReader.ReadByte();
                        }
                        // Assign DC Huffman Table.
                        if (tableClass == HuffmanTable.JPEG_DC_TABLE)
                        {
                            dcTables[(int)huffmanIndex] = new JpegHuffmanTable(codeLength, huffmanVal);
                        }

                        // Assign AC Huffman Table.
                        else if (tableClass == HuffmanTable.JPEG_AC_TABLE)
                        {
                            acTables[(int)huffmanIndex] = new JpegHuffmanTable(codeLength, huffmanVal);
                        }
                    }
                    break;

                case JPEGMarker.DQT:

                    // DQT non-SOF Marker - This defines the quantization
                    // coeffecients, this allows us to figure out the quality of
                    // compression and unencode the data. The data is loaded and
                    // then stored in to an array.
                    short quantizationLength = (short)(jpegReader.ReadShort() - 2);
                    for (int j = 0; j < quantizationLength / 65; j++)
                    {
                        byte  quantSpecs = jpegReader.ReadByte();
                        int[] quantData  = new int[64];
                        if ((byte)(quantSpecs >> 4) == 0)
                        // Precision 8 bit.
                        {
                            for (int i = 0; i < 64; i++)
                            {
                                quantData[i] = jpegReader.ReadByte();
                            }
                        }
                        else if ((byte)(quantSpecs >> 4) == 1)
                        // Precision 16 bit.
                        {
                            for (int i = 0; i < 64; i++)
                            {
                                quantData[i] = jpegReader.ReadShort();
                            }
                        }
                        qTables[(int)(quantSpecs & 0x0f)] = new JpegQuantizationTable(quantData);
                    }
                    break;

                case JPEGMarker.SOS:

                    Debug.WriteLine("Start of Scan (SOS)");


                    // SOS non-SOF Marker - Start Of Scan Marker, this is where the
                    // actual data is stored in a interlaced or non-interlaced with
                    // from 1-4 components of color data, if three components most
                    // likely a YCrCb model, this is a fairly complex process.

                    // Read in the scan length.
                    //ushort scanLen = jpegReader.ReadShort();
                    // Number of components in the scan.
                    byte   numberOfComponents = jpegReader.ReadByte();
                    byte[] componentSelector  = new byte[numberOfComponents];

                    for (int i = 0; i < numberOfComponents; i++)
                    {
                        // Component ID, packed byte containing the Id for the
                        // AC table and DC table.
                        byte componentID = jpegReader.ReadByte();
                        byte tableInfo   = jpegReader.ReadByte();

                        int DC = (tableInfo >> 4) & 0x0f;
                        int AC = (tableInfo) & 0x0f;

                        frame.setHuffmanTables(componentID,
                                               acTables[(byte)AC],
                                               dcTables[(byte)DC]);


                        componentSelector[i] = componentID;
                    }

                    byte startSpectralSelection  = jpegReader.ReadByte();
                    byte endSpectralSelection    = jpegReader.ReadByte();
                    byte successiveApproximation = jpegReader.ReadByte();

                    #region Baseline JPEG Scan Decoding

                    if (!progressive)
                    {
                        frame.DecodeScanBaseline(numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);
                        haveMarker = true;     // use resultant marker for the next switch(..)
                    }

                    #endregion

                    #region Progressive JPEG Scan Decoding

                    if (progressive)
                    {
                        frame.DecodeScanProgressive(
                            successiveApproximation, startSpectralSelection, endSpectralSelection,
                            numberOfComponents, componentSelector, resetInterval, jpegReader, ref marker);

                        haveMarker = true;     // use resultant marker for the next switch(..)
                    }

                    #endregion

                    break;


                case JPEGMarker.DRI:
                    jpegReader.BaseStream.Seek(2, System.IO.SeekOrigin.Current);
                    resetInterval = jpegReader.ReadShort();
                    break;

                // Defines the number of lines.  (Not usually present)
                case JPEGMarker.DNL:

                    frame.ScanLines = jpegReader.ReadShort();
                    break;

                // End of Image.  Finish the decode.
                case JPEGMarker.EOI:

                    if (jpegFrames.Count == 0)
                    {
                        throw new NotSupportedException("No JPEG frames could be located.");
                    }
                    else if (jpegFrames.Count == 1)
                    {
                        // Only one frame, JPEG Non-Heirarchial Frame.
                        byte[][,] raster = Image.CreateRaster(frame.Width, frame.Height, frame.ComponentCount);

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

                        int totalSteps    = components.Count * 3;  // Three steps per loop
                        int stepsFinished = 0;

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

                            comp.QuantizationTable = qTables[comp.quant_id].Table;

                            // 1. Quantize
                            comp.quantizeData();
                            UpdateProgress(++stepsFinished, totalSteps);

                            // 2. Run iDCT (expensive)
                            comp.idctData();
                            UpdateProgress(++stepsFinished, totalSteps);

                            // 3. Scale the image and write the data to the raster.
                            comp.writeDataScaled(raster, i, BlockUpsamplingMode);

                            UpdateProgress(++stepsFinished, totalSteps);

                            // Ensure garbage collection.
                            comp = null; GC.Collect();
                        }

                        // Grayscale Color Image (1 Component).
                        if (frame.ComponentCount == 1)
                        {
                            ColorModel cm = new ColorModel()
                            {
                                ColorSpace = ColorSpace.Gray, Opaque = true
                            };
                            image = new Image(cm, raster);
                        }
                        // YCbCr Color Image (3 Components).
                        else if (frame.ComponentCount == 3)
                        {
                            ColorModel cm = new ColorModel()
                            {
                                ColorSpace = ColorSpace.YCbCr, Opaque = true
                            };
                            image = new Image(cm, raster);
                        }
                        // Possibly CMYK or RGBA ?
                        else
                        {
                            throw new NotSupportedException("Unsupported Color Mode: 4 Component Color Mode found.");
                        }

                        // If needed, convert centimeters to inches.
                        Func <double, double> conv = x =>
                                                     Units == UnitType.Inches ? x : x / 2.54;

                        image.DensityX = conv(XDensity);
                        image.DensityY = conv(YDensity);

                        //height = frame.Height;
                        //width = frame.Width;
                    }
                    else
                    {
                        // JPEG Heirarchial Frame
                        throw new NotSupportedException("Unsupported Codec Type: Hierarchial JPEG");
                    }
                    break;

                // Only SOF0 (baseline) and SOF2 (progressive) are supported by FJCore
                case JPEGMarker.SOF1:
                case JPEGMarker.SOF3:
                case JPEGMarker.SOF5:
                case JPEGMarker.SOF6:
                case JPEGMarker.SOF7:
                case JPEGMarker.SOF9:
                case JPEGMarker.SOF10:
                case JPEGMarker.SOF11:
                case JPEGMarker.SOF13:
                case JPEGMarker.SOF14:
                case JPEGMarker.SOF15:
                    throw new NotSupportedException("Unsupported codec type.");

                default: break;      // ignore
                }

                #endregion switch over markers

                if (haveMarker)
                {
                    haveMarker = false;
                }
                else
                {
                    try
                    {
                        marker = jpegReader.GetNextMarker();
                    }
                    catch (System.IO.EndOfStreamException)
                    {
                        break; /* done reading the file */
                    }
                }
            }

            DecodedJpeg result = new DecodedJpeg(image, headers);

            return(result);
        }
Exemplo n.º 12
0
 public int mcus_per_row(JpegComponent c)
 {
     return(((Width * c.factorH + (Scan.MaxH - 1)) / Scan.MaxH + 7) / 8);
 }
Exemplo n.º 13
0
        private void DecodeScan(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
        {
            //TODO: not necessary
            jpegReader.eob_run = 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;

            //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

                try
                {
                    // 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)
                    {
                        JpegComponent comp = Scan.GetComponentById(componentSelector[0]);

                        comp.SetBlock(mcuIndex);

                        comp.DecodeMCU(jpegReader, h, v);

                        int mcus_per_line   = mcus_per_row(comp);
                        int blocks_per_line = (int)Math.Ceiling((double)this.Width / (8 * comp.factorH));


                        // TODO: Explain the non-interleaved scan ------

                        h++; x++;

                        if (h == comp.factorH)
                        {
                            h = 0; mcuIndex++;
                        }

                        if ((x % mcus_per_line) == 0)
                        {
                            x = 0;
                            v++;

                            if (v == comp.factorV)
                            {
                                if (h != 0)
                                {
                                    mcuIndex++; h = 0;
                                }
                                v = 0;
                            }
                            else
                            {
                                mcuIndex -= blocks_per_line;

                                // we were mid-block
                                if (h != 0)
                                {
                                    mcuIndex++; h = 0;
                                }
                            }
                        }

                        // -----------------------------------------------
                    }
                    else // Components are interleaved
                    {
                        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++)
                                {
                                    comp.DecodeMCU(jpegReader, i, j);
                                }
                            }
                        }

                        mcuIndex++;
                        mcuTotalIndex++;
                    }
                }
                // 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
                catch (JPEGMarkerFoundException ex)
                {
                    marker = ex.Marker;

                    // 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 compIndex = 0; compIndex < numberOfComponents; compIndex++)
                        {
                            JpegComponent comp = Scan.GetComponentById(componentSelector[compIndex]);
                            if (compIndex > 1)
                            {
                                comp.padMCU(mcuTotalIndex, resetInterval - mcuIndex);
                            }
                            comp.resetInterval();
                        }

                        mcuTotalIndex += (resetInterval - mcuIndex);
                        mcuIndex       = 0;
                    }
                    else
                    {
                        break; // We're at the end of our scan, exit out.
                    }
                }
            }
        }
Exemplo n.º 14
0
 private int mcus_per_row(JpegComponent c)
 {
     return(((((Width * c.factorH) + (Scan.MaxH - 1)) / Scan.MaxH) + 7) / 8);
 }
Exemplo n.º 15
0
        public void DecodeScan(byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
        {
            jpegReader.eob_run = 0;
            int  num      = 0;
            int  num2     = 0;
            int  num3     = 0;
            int  num4     = 0;
            int  num5     = 0;
            long position = jpegReader.BaseStream.Position;

            while (true)
            {
                if (ProgressUpdateMethod != null && jpegReader.BaseStream.Position >= position + JpegDecoder.ProgressUpdateByteInterval)
                {
                    position = jpegReader.BaseStream.Position;
                    ProgressUpdateMethod(position);
                }
                try
                {
                    if (numberOfComponents == 1)
                    {
                        JpegComponent componentById = Scan.GetComponentById(componentSelector[0]);
                        componentById.SetBlock(num);
                        componentById.DecodeMCU(jpegReader, num3, num4);
                        int num6 = mcus_per_row(componentById);
                        int num7 = (int)Math.Ceiling((double)(int)Width / (double)(8 * componentById.factorH));
                        num3++;
                        num5++;
                        if (num3 == componentById.factorH)
                        {
                            num3 = 0;
                            num++;
                        }
                        if (num5 % num6 == 0)
                        {
                            num5 = 0;
                            num4++;
                            if (num4 == componentById.factorV)
                            {
                                if (num3 != 0)
                                {
                                    num++;
                                    num3 = 0;
                                }
                                num4 = 0;
                            }
                            else
                            {
                                num -= num7;
                                if (num3 != 0)
                                {
                                    num++;
                                    num3 = 0;
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < numberOfComponents; i++)
                        {
                            JpegComponent componentById2 = Scan.GetComponentById(componentSelector[i]);
                            componentById2.SetBlock(num2);
                            for (int j = 0; j < componentById2.factorV; j++)
                            {
                                for (int k = 0; k < componentById2.factorH; k++)
                                {
                                    componentById2.DecodeMCU(jpegReader, k, j);
                                }
                            }
                        }
                        num++;
                        num2++;
                    }
                }
                catch (JPEGMarkerFoundException ex)
                {
                    marker = ex.Marker;
                    if (marker != 208 && marker != 209 && marker != 210 && marker != 211 && marker != 212 && marker != 213 && marker != 214 && marker != 215)
                    {
                        return;
                    }
                    for (int l = 0; l < numberOfComponents; l++)
                    {
                        JpegComponent componentById3 = Scan.GetComponentById(componentSelector[l]);
                        if (l > 1)
                        {
                            componentById3.padMCU(num2, resetInterval - num);
                        }
                        componentById3.resetInterval();
                    }
                    num2 += resetInterval - num;
                    num   = 0;
                }
            }
        }
Exemplo n.º 16
0
        public void DecodeScanProgressive(byte successiveApproximation, byte startSpectralSelection, byte endSpectralSelection,
                                          byte numberOfComponents, byte[] componentSelector, int resetInterval, JPEGBinaryReader jpegReader, ref byte marker)
        {
            byte successiveHigh = (byte)(successiveApproximation >> 4);
            byte 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);
        }
Exemplo n.º 17
0
 private int mcus_per_row(JpegComponent c)
 {
     return (((( Width * c.factorH ) + ( Scan.MaxH - 1)) / Scan.MaxH) + 7) / 8;
 }
Exemplo n.º 18
0
        public DecodedJpeg Decode()
        {
            JPEGFrame         jPEGFrame     = null;
            int               resetInterval = 0;
            bool              flag          = false;
            bool              flag2         = false;
            List <JpegHeader> list          = new List <JpegHeader>();

            while (true)
            {
                if (DecodeProgress.Abort)
                {
                    return(null);
                }
                switch (marker)
                {
                case 224:
                case 225:
                case 226:
                case 227:
                case 228:
                case 229:
                case 230:
                case 231:
                case 232:
                case 233:
                case 234:
                case 235:
                case 236:
                case 237:
                case 238:
                case 239:
                case 254:
                {
                    JpegHeader jpegHeader = ExtractHeader();
                    if (jpegHeader.Marker == 225 && jpegHeader.Data.Length >= 6)
                    {
                        byte[] data = jpegHeader.Data;
                        if (data[0] == 69 && data[1] == 120 && data[2] == 105 && data[3] == 102 && data[4] == 0)
                        {
                            _ = data[5];
                        }
                    }
                    if (jpegHeader.Data.Length >= 5 && jpegHeader.Marker == 238)
                    {
                        _ = (Encoding.UTF8.GetString(jpegHeader.Data, 0, 5) == "Adobe");
                    }
                    list.Add(jpegHeader);
                    if (flag2 || marker != 224)
                    {
                        break;
                    }
                    flag2 = TryParseJFIF(jpegHeader.Data);
                    if (flag2)
                    {
                        jpegHeader.IsJFIF = true;
                        marker            = jpegReader.GetNextMarker();
                        if (marker == 224)
                        {
                            jpegHeader = ExtractHeader();
                            list.Add(jpegHeader);
                        }
                        else
                        {
                            flag = true;
                        }
                    }
                    break;
                }

                case 192:
                case 194:
                {
                    progressive = (marker == 194);
                    jpegFrames.Add(new JPEGFrame());
                    jPEGFrame = jpegFrames[jpegFrames.Count - 1];
                    jPEGFrame.ProgressUpdateMethod = UpdateStreamProgress;
                    jpegReader.ReadShort();
                    jPEGFrame.setPrecision(jpegReader.ReadByte());
                    jPEGFrame.ScanLines      = jpegReader.ReadShort();
                    jPEGFrame.SamplesPerLine = jpegReader.ReadShort();
                    jPEGFrame.ComponentCount = jpegReader.ReadByte();
                    DecodeProgress.Height    = jPEGFrame.Height;
                    DecodeProgress.Width     = jPEGFrame.Width;
                    DecodeProgress.SizeReady = true;
                    if (this.DecodeProgressChanged != null)
                    {
                        this.DecodeProgressChanged(this, DecodeProgress);
                        if (DecodeProgress.Abort)
                        {
                            return(null);
                        }
                    }
                    for (int m = 0; m < jPEGFrame.ComponentCount; m++)
                    {
                        byte componentID         = jpegReader.ReadByte();
                        byte num5                = jpegReader.ReadByte();
                        byte quantizationTableID = jpegReader.ReadByte();
                        byte sampleHFactor       = (byte)(num5 >> 4);
                        byte sampleVFactor       = (byte)(num5 & 0xF);
                        jPEGFrame.AddComponent(componentID, sampleHFactor, sampleVFactor, quantizationTableID);
                    }
                    break;
                }

                case 196:
                {
                    int num2 = jpegReader.ReadShort() - 2;
                    while (num2 > 0)
                    {
                        byte    num3  = jpegReader.ReadByte();
                        byte    b     = (byte)(num3 >> 4);
                        byte    b2    = (byte)(num3 & 0xF);
                        short[] array = new short[16];
                        for (int j = 0; j < array.Length; j++)
                        {
                            array[j] = jpegReader.ReadByte();
                        }
                        int num4 = 0;
                        for (int k = 0; k < 16; k++)
                        {
                            num4 += array[k];
                        }
                        num2 -= num4 + 17;
                        short[] array2 = new short[num4];
                        for (int l = 0; l < array2.Length; l++)
                        {
                            array2[l] = jpegReader.ReadByte();
                        }
                        if (b == HuffmanTable.JPEG_DC_TABLE)
                        {
                            dcTables[b2] = new JpegHuffmanTable(array, array2);
                        }
                        else if (b == HuffmanTable.JPEG_AC_TABLE)
                        {
                            acTables[b2] = new JpegHuffmanTable(array, array2);
                        }
                    }
                    break;
                }

                case 219:
                {
                    short num9 = (short)(jpegReader.ReadShort() - 2);
                    for (int num10 = 0; num10 < num9 / 65; num10++)
                    {
                        byte  b5     = jpegReader.ReadByte();
                        int[] array4 = new int[64];
                        if ((byte)(b5 >> 4) == 0)
                        {
                            for (int num11 = 0; num11 < 64; num11++)
                            {
                                array4[num11] = jpegReader.ReadByte();
                            }
                        }
                        else if ((byte)(b5 >> 4) == 1)
                        {
                            for (int num12 = 0; num12 < 64; num12++)
                            {
                                array4[num12] = jpegReader.ReadShort();
                            }
                        }
                        qTables[b5 & 0xF] = new JpegQuantizationTable(array4);
                    }
                    break;
                }

                case 218:
                {
                    jpegReader.ReadShort();
                    byte   b3     = jpegReader.ReadByte();
                    byte[] array3 = new byte[b3];
                    for (int n = 0; n < b3; n++)
                    {
                        byte b4   = jpegReader.ReadByte();
                        byte num6 = jpegReader.ReadByte();
                        int  num7 = (num6 >> 4) & 0xF;
                        int  num8 = num6 & 0xF;
                        jPEGFrame.setHuffmanTables(b4, acTables[(byte)num8], dcTables[(byte)num7]);
                        array3[n] = b4;
                    }
                    byte startSpectralSelection  = jpegReader.ReadByte();
                    byte endSpectralSelection    = jpegReader.ReadByte();
                    byte successiveApproximation = jpegReader.ReadByte();
                    if (!progressive)
                    {
                        jPEGFrame.DecodeScanBaseline(b3, array3, resetInterval, jpegReader, ref marker);
                        flag = true;
                    }
                    if (progressive)
                    {
                        jPEGFrame.DecodeScanProgressive(successiveApproximation, startSpectralSelection, endSpectralSelection, b3, array3, resetInterval, jpegReader, ref marker);
                        flag = true;
                    }
                    break;
                }

                case 221:
                    jpegReader.BaseStream.Seek(2L, SeekOrigin.Current);
                    resetInterval = jpegReader.ReadShort();
                    break;

                case 220:
                    jPEGFrame.ScanLines = jpegReader.ReadShort();
                    break;

                case 217:
                {
                    if (jpegFrames.Count == 0)
                    {
                        throw new NotSupportedException("No JPEG frames could be located.");
                    }
                    if (jpegFrames.Count > 1)
                    {
                        jPEGFrame = jpegFrames.OrderByDescending((JPEGFrame f) => f.Width * f.Height).FirstOrDefault();
                    }
                    byte[][,] raster = Image.CreateRaster(jPEGFrame.Width, jPEGFrame.Height, jPEGFrame.ComponentCount);
                    IList <JpegComponent> components = jPEGFrame.Scan.Components;
                    int stepsTotal = components.Count * 3;
                    int num        = 0;
                    for (int i = 0; i < components.Count; i++)
                    {
                        JpegComponent jpegComponent = components[i];
                        jpegComponent.QuantizationTable = qTables[jpegComponent.quant_id].Table;
                        jpegComponent.quantizeData();
                        UpdateProgress(++num, stepsTotal);
                        jpegComponent.idctData();
                        UpdateProgress(++num, stepsTotal);
                        jpegComponent.writeDataScaled(raster, i, BlockUpsamplingMode);
                        UpdateProgress(++num, stepsTotal);
                        jpegComponent = null;
                        GC.Collect();
                    }
                    ColorModel colorModel;
                    if (jPEGFrame.ComponentCount == 1)
                    {
                        colorModel            = default(ColorModel);
                        colorModel.colorspace = ColorSpace.Gray;
                        colorModel.Opaque     = true;
                        ColorModel cm = colorModel;
                        image = new Image(cm, raster);
                    }
                    else
                    {
                        if (jPEGFrame.ComponentCount != 3)
                        {
                            throw new NotSupportedException("Unsupported Color Mode: 4 Component Color Mode found.");
                        }
                        colorModel            = default(ColorModel);
                        colorModel.colorspace = ColorSpace.YCbCr;
                        colorModel.Opaque     = true;
                        ColorModel cm2 = colorModel;
                        image = new Image(cm2, raster);
                    }
                    Func <double, double> func = (double x) => (Units != UnitType.Inches) ? (x / 2.54) : x;
                    image.DensityX = func((int)XDensity);
                    image.DensityY = func((int)YDensity);
                    break;
                }

                case 193:
                case 195:
                case 197:
                case 198:
                case 199:
                case 201:
                case 202:
                case 203:
                case 205:
                case 206:
                case 207:
                    throw new NotSupportedException("Unsupported codec type.");
                }
                if (flag)
                {
                    flag = false;
                }
                else
                {
                    try
                    {
                        marker = jpegReader.GetNextMarker();
                    }
                    catch (EndOfStreamException)
                    {
                        break;
                    }
                }
            }
            return(new DecodedJpeg(image, list));
        }