Example #1
0
        private void AddIptcProperties(JpegHeader header)
        {
            IptcFile iptc = header.GetIptc();

            if (iptc == null)
            {
                return;
            }

            foreach (DataSet data in iptc.Sets)
            {
                switch (data.ID)
                {
                case DataSetID.ContentLocationName:
                    AddProperty(Beagle.Property.New("iptc:location", data.XmpObject));
                    break;

                case DataSetID.CaptionAbstract:
                    AddProperty(Beagle.Property.New("iptc:caption", data.XmpObject));
                    break;

                case DataSetID.Keywords:
                    AddProperty(Beagle.Property.NewKeyword("iptc:keyword", data.XmpObject));
                    AddProperty(Beagle.Property.NewUnstored("image:tag", data.XmpObject));
                    break;

                default:
                    // FIXME: Anything else to index ?
                    //Log.Debug ("Ignoring {0} = [{1}]", data.ID, data.XmpObject);
                    break;
                }
            }
        }
Example #2
0
    public static int Main(string [] args)
    {
        JpegHeader data = new JpegHeader(args [0]);

        byte [] value = data.GetRawXmp();

        if (value != null)
        {
            string xml = System.Text.Encoding.UTF8.GetString(value, 29, value.Length - 29);
            //System.Console.WriteLine (xml);
        }

        value = data.GetRaw("ICC_PROFILE");
        if (value != null)
        {
            System.IO.FileStream stream = new System.IO.FileStream("profile.icc", System.IO.FileMode.Create);
            stream.Write(value, 12, value.Length - 12);
            stream.Close();
        }

        value = data.GetRawExif();


        //System.IO.Stream ostream = System.IO.File.Open ("/home/lewing/test.jpg", System.IO.FileMode.OpenOrCreate);
        //data.Save (ostream);
        //ostream.Position = 0;
        //data = new JpegHeader (ostream);

        return(0);
    }
Example #3
0
        private void AddXmpProperties(JpegHeader header)
        {
            XmpFile xmp = header.GetXmp();

            if (xmp != null)
            {
                AddXmpProperties(xmp);
            }
        }
Example #4
0
 public void Select(SemWeb.StatementSink sink)
 {
     byte [] data = GetEmbeddedJpeg();
     if (data != null)
     {
         System.IO.Stream stream = new System.IO.MemoryStream(data);
         JpegHeader       header = new JpegHeader(stream);
         header.Select(sink);
     }
 }
Example #5
0
        // FIXME: This is not particularly efficient
        protected override void PullImageProperties()
        {
            JpegHeader header = new JpegHeader(Stream);

            AddJfifProperties(header);
            AddExifProperties(header);
            AddXmpProperties(header);
            AddIptcProperties(header);

            Finished();              // That's all folks...
        }
Example #6
0
        //public DecodedJpeg Decode()
        //{
        //    JPEGFrame frame = null;
        //    int num2;
        //    Func<double, double> func2 = null;
        //    bool flag3;
        //    int resetInterval = 0;
        //    bool flag = false;
        //    bool flag2 = false;
        //    List<JpegHeader> metaHeaders = new List<JpegHeader>();
        //    goto Label_09C3;
        //Label_03AF:
        //    num2 = 0;
        //    while (num2 < frame.ComponentCount)
        //    {
        //        byte componentID = this.jpegReader.ReadByte();
        //        byte num4 = this.jpegReader.ReadByte();
        //        byte quantizationTableID = this.jpegReader.ReadByte();
        //        byte sampleHFactor = (byte)(num4 >> 4);
        //        byte sampleVFactor = (byte)(num4 & 15);
        //        frame.AddComponent(componentID, sampleHFactor, sampleVFactor, quantizationTableID);
        //        num2++;
        //    }
        //Label_0998:
        //    if (flag)
        //    {
        //        flag = false;
        //    }
        //    else
        //    {
        //        try
        //        {
        //            this.marker = this.jpegReader.GetNextMarker();
        //        }
        //        catch (EndOfStreamException)
        //        {
        //            return new DecodedJpeg(this.image, metaHeaders);
        //        }
        //    }
        //Label_09C3:
        //    flag3 = true;
        //    if (this.DecodeProgress.Abort)
        //    {
        //        return null;
        //    }
        //    switch (this.marker)
        //    {
        //        case 0xc0:
        //        case 0xc2:
        //            this.progressive = this.marker == 0xc2;
        //            this.jpegFrames.Add(new JPEGFrame());
        //            frame = this.jpegFrames[this.jpegFrames.Count - 1];
        //            frame.ProgressUpdateMethod = new Action<long>(this.UpdateStreamProgress);
        //            this.jpegReader.ReadShort();
        //            frame.setPrecision(this.jpegReader.ReadByte());
        //            frame.ScanLines = this.jpegReader.ReadShort();
        //            frame.SamplesPerLine = this.jpegReader.ReadShort();
        //            frame.ComponentCount = this.jpegReader.ReadByte();
        //            this.DecodeProgress.Height = frame.Height;
        //            this.DecodeProgress.Width = frame.Width;
        //            this.DecodeProgress.SizeReady = true;
        //            if (this.DecodeProgressChanged == null)
        //            {
        //                goto Label_03AF;
        //            }
        //            this.DecodeProgressChanged(this, this.DecodeProgress);
        //            if (!this.DecodeProgress.Abort)
        //            {
        //                goto Label_03AF;
        //            }
        //            return null;

        //        case 0xc1:
        //        case 0xc3:
        //        case 0xc5:
        //        case 0xc6:
        //        case 0xc7:
        //        case 0xc9:
        //        case 0xca:
        //        case 0xcb:
        //        case 0xcd:
        //        case 0xce:
        //        case 0xcf:
        //            throw new NotSupportedException("Unsupported codec type.");

        //        case 0xc4:
        //            {
        //                int num8 = this.jpegReader.ReadShort() - 2;
        //                int num9 = num8;
        //                while (num9 > 0)
        //                {
        //                    byte num10 = this.jpegReader.ReadByte();
        //                    byte num11 = (byte)(num10 >> 4);
        //                    byte index = (byte)(num10 & 15);
        //                    short[] lengths = new short[0x10];
        //                    for (num2 = 0; num2 < lengths.Length; num2++)
        //                    {
        //                        lengths[num2] = this.jpegReader.ReadByte();
        //                    }
        //                    int num13 = 0;
        //                    for (num2 = 0; num2 < 0x10; num2++)
        //                    {
        //                        num13 += lengths[num2];
        //                    }
        //                    num9 -= num13 + 0x11;
        //                    short[] values = new short[num13];
        //                    for (num2 = 0; num2 < values.Length; num2++)
        //                    {
        //                        values[num2] = this.jpegReader.ReadByte();
        //                    }
        //                    if (num11 == HuffmanTable.JPEG_DC_TABLE)
        //                    {
        //                        this.dcTables[index] = new JpegHuffmanTable(lengths, values);
        //                    }
        //                    else if (num11 == HuffmanTable.JPEG_AC_TABLE)
        //                    {
        //                        this.acTables[index] = new JpegHuffmanTable(lengths, values);
        //                    }
        //                }
        //                goto Label_0998;
        //            }
        //        case 200:
        //        case 0xcc:
        //        case 0xd0:
        //        case 0xd1:
        //        case 210:
        //        case 0xd3:
        //        case 0xd4:
        //        case 0xd5:
        //        case 0xd6:
        //        case 0xd7:
        //        case 0xd8:
        //        case 0xde:
        //        case 0xdf:
        //        case 240:
        //        case 0xf1:
        //        case 0xf2:
        //        case 0xf3:
        //        case 0xf4:
        //        case 0xf5:
        //        case 0xf6:
        //        case 0xf7:
        //        case 0xf8:
        //        case 0xf9:
        //        case 250:
        //        case 0xfb:
        //        case 0xfc:
        //        case 0xfd:
        //            goto Label_0998;

        //        case 0xd9:
        //            {
        //                ColorModel model;
        //                ColorModel model4;
        //                if (this.jpegFrames.Count == 0)
        //                {
        //                    throw new NotSupportedException("No JPEG frames could be located.");
        //                }
        //                if (this.jpegFrames.Count != 1)
        //                {
        //                    throw new NotSupportedException("Unsupported Codec Type: Hierarchial JPEG");
        //                }
        //                byte[][,] raster = Image.CreateRaster(frame.Width, frame.Height, frame.ComponentCount);
        //                IList<JpegComponent> components = frame.Scan.Components;
        //                int stepsTotal = components.Count * 3;
        //                int num27 = 0;
        //                for (num2 = 0; num2 < components.Count; num2++)
        //                {
        //                    JpegComponent component = components[num2];
        //                    component.QuantizationTable = this.qTables[component.quant_id].Table;
        //                    component.quantizeData();
        //                    this.UpdateProgress(++num27, stepsTotal);
        //                    component.idctData();
        //                    this.UpdateProgress(++num27, stepsTotal);
        //                    component.writeDataScaled(raster, num2, this.BlockUpsamplingMode);
        //                    this.UpdateProgress(++num27, stepsTotal);
        //                    component = null;
        //                    GC.Collect();
        //                }
        //                if (frame.ComponentCount == 1)
        //                {
        //                    model4 = new ColorModel();
        //                    ColorModel model2 = model4;
        //                    model2.colorspace = ColorSpace.Gray;
        //                    model2.Opaque = true;
        //                    model = model2;
        //                    this.image = new Image(model, raster);
        //                }
        //                else
        //                {
        //                    if (frame.ComponentCount != 3)
        //                    {
        //                        throw new NotSupportedException("Unsupported Color Mode: 4 Component Color Mode found.");
        //                    }
        //                    model4 = new ColorModel();
        //                    ColorModel model3 = model4;
        //                    model3.colorspace = ColorSpace.YCbCr;
        //                    model3.Opaque = true;
        //                    model = model3;
        //                    this.image = new Image(model, raster);
        //                }
        //                if (func2 == null)
        //                {
        //                    func2 = delegate(double x)
        //                    {
        //                        return (this.Units == UnitType.Inches) ? x : (x / 2.54);
        //                    };
        //                }
        //                Func<double, double> func = func2;
        //                this.image.DensityX = func((double)this.XDensity);
        //                this.image.DensityY = func((double)this.YDensity);
        //                this.height = frame.Height;
        //                this.width = frame.Width;
        //                goto Label_0998;
        //            }
        //        case 0xda:
        //            {
        //                Debug.WriteLine("Start of Scan (SOS)");
        //                ushort num17 = this.jpegReader.ReadShort();
        //                byte numberOfComponents = this.jpegReader.ReadByte();
        //                byte[] componentSelector = new byte[numberOfComponents];
        //                num2 = 0;
        //                while (num2 < numberOfComponents)
        //                {
        //                    byte num19 = this.jpegReader.ReadByte();
        //                    byte num20 = this.jpegReader.ReadByte();
        //                    int num21 = (num20 >> 4) & 15;
        //                    int num22 = num20 & 15;
        //                    frame.setHuffmanTables(num19, this.acTables[(byte)num22], this.dcTables[(byte)num21]);
        //                    componentSelector[num2] = num19;
        //                    num2++;
        //                }
        //                byte startSpectralSelection = this.jpegReader.ReadByte();
        //                byte endSpectralSelection = this.jpegReader.ReadByte();
        //                byte successiveApproximation = this.jpegReader.ReadByte();
        //                if (!this.progressive)
        //                {
        //                    frame.DecodeScanBaseline(numberOfComponents, componentSelector, resetInterval, this.jpegReader, ref this.marker);
        //                    flag = true;
        //                }
        //                if (this.progressive)
        //                {
        //                    frame.DecodeScanProgressive(successiveApproximation, startSpectralSelection, endSpectralSelection, numberOfComponents, componentSelector, resetInterval, this.jpegReader, ref this.marker);
        //                    flag = true;
        //                }
        //                goto Label_0998;
        //            }
        //        case 0xdb:
        //            {
        //                short num14 = (short)(this.jpegReader.ReadShort() - 2);
        //                for (int i = 0; i < (num14 / 0x41); i++)
        //                {
        //                    byte num16 = this.jpegReader.ReadByte();
        //                    int[] table = new int[0x40];
        //                    if (((byte)(num16 >> 4)) == 0)
        //                    {
        //                        for (num2 = 0; num2 < 0x40; num2++)
        //                        {
        //                            table[num2] = this.jpegReader.ReadByte();
        //                        }
        //                    }
        //                    else if (((byte)(num16 >> 4)) == 1)
        //                    {
        //                        for (num2 = 0; num2 < 0x40; num2++)
        //                        {
        //                            table[num2] = this.jpegReader.ReadShort();
        //                        }
        //                    }
        //                    this.qTables[num16 & 15] = new JpegQuantizationTable(table);
        //                }
        //                goto Label_0998;
        //            }
        //        case 220:
        //            frame.ScanLines = this.jpegReader.ReadShort();
        //            goto Label_0998;

        //        case 0xdd:
        //            this.jpegReader.BaseStream.Seek(2L, SeekOrigin.Current);
        //            resetInterval = this.jpegReader.ReadShort();
        //            goto Label_0998;

        //        case 0xe0:
        //        case 0xe1:
        //        case 0xe2:
        //        case 0xe3:
        //        case 0xe4:
        //        case 0xe5:
        //        case 230:
        //        case 0xe7:
        //        case 0xe8:
        //        case 0xe9:
        //        case 0xea:
        //        case 0xeb:
        //        case 0xec:
        //        case 0xed:
        //        case 0xee:
        //        case 0xef:
        //        case 0xfe:
        //            {
        //                JpegHeader item = this.ExtractHeader();
        //                if ((item.Marker == 0xe1) && (item.Data.Length >= 6))
        //                {
        //                    byte[] data = item.Data;
        //                    if (((((data[0] == 0x45) && (data[1] == 120)) && ((data[2] == 0x69) && (data[3] == 0x66))) && (data[4] == 0)) && (data[5] == 0))
        //                    {
        //                    }
        //                }
        //                if (((item.Data.Length >= 5) && (item.Marker == 0xee)) && (Encoding.UTF8.GetString(item.Data, 0, 5) == "Adobe"))
        //                {
        //                }
        //                metaHeaders.Add(item);
        //                if ((!flag2 && (this.marker == 0xe0)) && this.TryParseJFIF(item.Data))
        //                {
        //                    item.IsJFIF = true;
        //                    this.marker = this.jpegReader.GetNextMarker();
        //                    if (this.marker == 0xe0)
        //                    {
        //                        item = this.ExtractHeader();
        //                        metaHeaders.Add(item);
        //                    }
        //                    else
        //                    {
        //                        flag = true;
        //                    }
        //                }
        //                goto Label_0998;
        //            }
        //    }
        //    goto Label_0998;
        //}

        private JpegHeader ExtractHeader()
        {
            int count = this.jpegReader.ReadShort() - 2;

            byte[] buffer = new byte[count];
            this.jpegReader.Read(buffer, 0, count);
            JpegHeader header2 = new JpegHeader();

            header2.Marker = this.marker;
            header2.Data   = buffer;
            return(header2);
        }
Example #7
0
		public override Stream PixbufStream ()
		{
			if (header != null)
				return Open ();

			Stream s = Open ();
			if (s.CanSeek) {
				header = new JpegHeader (s, true);
				s.Position = 0;
			} else
				Console.WriteLine ("{0} can not seek :(", s);
			return s;
		}
Example #8
0
        public void Save()
        {
            string     in_path  = CreateFile();
            string     out_path = ImageFile.TempPath("output.jpg");
            JpegHeader source;
            JpegHeader dest;

            using (Stream orig = File.OpenRead(in_path)) {
                source = new JpegHeader(orig);

                using (Stream output = File.OpenWrite(out_path)) {
                    source.Save(output);
                }

                using (Stream result = File.OpenRead(out_path)) {
                    dest = new JpegHeader(result);

                    Assert.AreEqual(source.Markers.Count, dest.Markers.Count);
                    Assert.AreEqual(source.GuessQuality(), dest.GuessQuality());
                    Assert.AreEqual(orig.Length, result.Length);
                    for (int i = 0; i < source.Markers.Count; i++)
                    {
                        Marker d = (Marker)dest.Markers [i];
                        Marker s = (Marker)source.Markers [i];

                        Assert.AreEqual(d.Type, s.Type);
                        Assert.AreEqual(d.GetName(), s.GetName());

                        if (d.Data != null)
                        {
                            Assert.AreEqual(d.Data.Length, s.Data.Length);

                            for (int j = 0; j < d.Data.Length; j++)
                            {
                                Assert.AreEqual(d.Data [j], s.Data [j]);
                            }
                        }
                        else
                        {
                            Assert.AreEqual(d.Data, s.Data);
                        }
                    }
                }
            }

            File.Delete(in_path);
            File.Delete(out_path);
        }
Example #9
0
        private JpegHeader ExtractHeader()
        {
            #region Extract the header

            int    length = jpegReader.ReadShort() - 2;
            byte[] data   = new byte[length];
            jpegReader.Read(data, 0, length);

            #endregion

            JpegHeader header = new JpegHeader()
            {
                Marker = marker,
                Data   = data
            };
            return(header);
        }
Example #10
0
        private void SaveMetaData(System.IO.Stream input, System.IO.Stream output)
        {
            JpegHeader header = new JpegHeader(input);

            UpdateMeta();

            // Console.WriteLine ("updated metadata");
            header.SetExif(this.ExifData);
            // Console.WriteLine ("set exif");
            if (xmp != null)
            {
                header.SetXmp(xmp);
            }
            // Console.WriteLine ("set xmp");
            header.Save(output);
            // Console.WriteLine ("saved");
        }
Example #11
0
        public void Load()
        {
            string path = CreateFile();

            using (Stream stream = File.OpenRead(path)) {
                JpegHeader jhead = new JpegHeader(stream);

                Assert.AreEqual(((Marker)jhead.Markers [0]).Type, JpegMarker.Soi);
                Assert.AreEqual(((Marker)jhead.Markers [1]).GetName(), "JFIF");
                Assert.AreEqual(((Marker)jhead.Markers [1]).Type, JpegMarker.App0);
                Assert.AreEqual(((Marker)jhead.Markers [2]).GetName(), "Exif");
                Assert.AreEqual(((Marker)jhead.Markers [2]).Type, JpegMarker.App1);

                // NOTE the currently we don't store the Eoi as the last marker
                Assert.AreEqual(((Marker)jhead.Markers [jhead.Markers.Count - 1]).Type, JpegMarker.Sos);

                // NOTE this is kind of sill but it might help
                Assert.IsTrue(Math.Abs(jhead.GuessQuality() - quality) <= 1);

                Assert.IsNotNull(jhead.GetExifHeader());
            }

            File.Delete(path);
        }
Example #12
0
		public void Select (SemWeb.StatementSink sink)
		{
			byte [] data = GetEmbeddedJpeg ();
			if (data != null) {
				System.IO.Stream stream = new System.IO.MemoryStream (data);
				JpegHeader header = new JpegHeader (stream);
				header.Select (sink);
			}
		}
Example #13
0
	public static int Main (string [] args)
	{
		JpegHeader data = new JpegHeader (args [0]);
		byte [] value = data.GetRawXmp ();

		if (value != null) {
			string xml = System.Text.Encoding.UTF8.GetString (value, 29, value.Length - 29);
			//System.Console.WriteLine (xml);
		}
		
		value = data.GetRaw ("ICC_PROFILE");
		if (value != null) {
			System.IO.FileStream stream = new System.IO.FileStream ("profile.icc", System.IO.FileMode.Create);
			stream.Write (value, 12, value.Length - 12);
			stream.Close ();
		}

		value = data.GetRawExif ();
		
		
		//System.IO.Stream ostream = System.IO.File.Open ("/home/lewing/test.jpg", System.IO.FileMode.OpenOrCreate);
		//data.Save (ostream);
		//ostream.Position = 0;
		//data = new JpegHeader (ostream);

		return 0;
	}
        private JpegHeader ExtractHeader()
        {
            #region Extract the header

            int length = jpegReader.ReadShort() - 2;
            byte[] data = new byte[length];
            jpegReader.Read(data, 0, length);

            #endregion

            JpegHeader header = new JpegHeader()
            {
                Marker = marker,
                Data = data
            };
            return header;
        }
Example #15
0
		public void Load ()
		{
			string path = CreateFile ();

			using (Stream stream = File.OpenRead (path)) {
				JpegHeader jhead = new JpegHeader (stream);

				Assert.AreEqual (((Marker)jhead.Markers [0]).Type, JpegMarker.Soi);
				Assert.AreEqual (((Marker)jhead.Markers [1]).GetName (), "JFIF");
				Assert.AreEqual (((Marker)jhead.Markers [1]).Type, JpegMarker.App0);
				Assert.AreEqual (((Marker)jhead.Markers [2]).GetName (), "Exif");
				Assert.AreEqual (((Marker)jhead.Markers [2]).Type, JpegMarker.App1);

				// NOTE the currently we don't store the Eoi as the last marker
				Assert.AreEqual (((Marker)jhead.Markers [jhead.Markers.Count -1]).Type, JpegMarker.Sos);

				// NOTE this is kind of sill but it might help
				Assert.IsTrue (Math.Abs (jhead.GuessQuality () - quality) <= 1);

				Assert.IsNotNull (jhead.GetExifHeader ());
			}

			File.Delete (path);
		}
Example #16
0
		public void Save ()
		{
			string in_path = CreateFile ();
			string out_path = ImageFile.TempPath ("output.jpg");
			JpegHeader source;
			JpegHeader dest;

			using (Stream orig = File.OpenRead (in_path)) {
				source = new JpegHeader (orig);
				
				using (Stream output = File.OpenWrite (out_path)) {
					source.Save (output);
				}

				using (Stream result = File.OpenRead (out_path)) {
					dest = new JpegHeader (result);
					
					Assert.AreEqual (source.Markers.Count, dest.Markers.Count);
					Assert.AreEqual (source.GuessQuality (), dest.GuessQuality ());
					Assert.AreEqual (orig.Length, result.Length);
					for (int i = 0; i < source.Markers.Count; i++) {
						Marker d = (Marker) dest.Markers [i];
						Marker s = (Marker) source.Markers [i];

						Assert.AreEqual (d.Type, s.Type);
						Assert.AreEqual (d.GetName (), s.GetName ());

						if (d.Data != null) {
							Assert.AreEqual (d.Data.Length, s.Data.Length);
						
							for (int j = 0; j < d.Data.Length; j++) {
								Assert.AreEqual (d.Data [j], s.Data [j]);
							}
						} else {
							Assert.AreEqual (d.Data, s.Data);
						}
					}
				}
			}

			File.Delete (in_path);
			File.Delete (out_path);
		}
Example #17
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));
        }
Example #18
0
        private void AddExifProperties(JpegHeader header)
        {
            Tiff.Header ifd = header.GetExifHeader();
            if (ifd == null)
            {
                return;
            }
            //ifd.Dump ("foo"); // Uncomment to debug

            string str;

            Tiff.DirectoryEntry entry;

            // Add IFD 0 properies

            str = GetExifString(ifd.Directory, Tiff.TagId.Model);
            AddProperty(Beagle.Property.New("exif:Model", str));

            str = GetExifString(ifd.Directory, Tiff.TagId.ImageDescription);
            AddProperty(Beagle.Property.New("exif:ImageDescription", str));

            try {
                entry = ifd.Directory.Lookup(Tiff.TagId.DateTime);
                if (entry != null)
                {
                    // Assume datetime stored in the images are local times
                    AddProperty(Beagle.Property.NewDate("exif:DateTime", entry.ValueAsDate.ToUniversalTime()));
                }
            } catch (FormatException) {
                Logger.Log.Debug("EXIF DateTime '{0}' is invalid.", GetExifString(ifd.Directory, Tiff.TagId.DateTime));
            } catch (ArgumentOutOfRangeException) {
                Logger.Log.Debug("EXIF DateTime '{0}' is invalid.", GetExifString(ifd.Directory, Tiff.TagId.DateTime));
            }

            str = GetExifString(ifd.Directory, Tiff.TagId.Copyright);
            AddProperty(Beagle.Property.New("dc:rights", str));

            // Add IFD 1 properties

            Tiff.SubdirectoryEntry subdir = (Tiff.SubdirectoryEntry)ifd.Directory.Lookup(Tiff.TagId.ExifIfdPointer);
            if (subdir == null)
            {
                return;
            }

            Tiff.ImageDirectory exif = subdir.Directory [0];
            if (exif == null)
            {
                return;
            }

            entry = exif.Lookup(Tiff.TagId.UserComment);
            if (entry != null)
            {
                AddProperty(Beagle.Property.New("exif:UserComment", entry.UserCommentValue));
            }

            uint val = 0;

            entry = exif.Lookup(Tiff.TagId.PixelXDimension);
            if (entry != null)
            {
                val = entry.ValueAsLong [0];
            }
            if (val > 0)
            {
                Width = (int)val;
                AddProperty(Beagle.Property.NewUnsearched("exif:PixelXDimension", val));
            }

            val   = 0;
            entry = exif.Lookup(Tiff.TagId.PixelYDimension);
            if (entry != null)
            {
                val = entry.ValueAsLong [0];
            }
            if (val > 0)
            {
                Height = (int)val;
                AddProperty(Beagle.Property.NewUnsearched("exif:PixelYDimension", val));
            }

            str = GetExifString(exif, Tiff.TagId.ISOSpeedRatings);
            AddProperty(Beagle.Property.NewUnsearched("exif:ISOSpeedRatings", str));

            str = GetExifString(exif, Tiff.TagId.ShutterSpeedValue);
            AddProperty(Beagle.Property.NewUnsearched("exif:ShutterSpeedValue", str));

            str = GetExifString(exif, Tiff.TagId.ExposureTime);
            if (!String.IsNullOrEmpty(str))
            {
                AddProperty(Beagle.Property.NewUnsearched("exif:ExposureTime", str + " sec."));
            }

            double rational_val;

            rational_val = GetExifRational(exif, Tiff.TagId.FNumber);
            if (rational_val > 0)
            {
                AddProperty(Beagle.Property.NewUnsearched("exif:FNumber", String.Format("f/{0}", rational_val)));
            }

            rational_val = GetExifRational(exif, Tiff.TagId.ApertureValue);
            if (rational_val > 0)
            {
                AddProperty(Beagle.Property.NewUnsearched("exif:ApertureValue", rational_val));
            }

            rational_val = GetExifRational(exif, Tiff.TagId.FocalLength);
            if (rational_val > 0)
            {
                AddProperty(Beagle.Property.NewUnsearched("exif:FocalLength", String.Format("{0} mm", rational_val)));
            }

            entry = exif.Lookup(Tiff.TagId.Flash);
            if (entry != null)
            {
                ushort flash = entry.ShortValue [0];
                AddProperty(Beagle.Property.NewUnsearched("exif:Flash", GetFlashString(flash)));
            }
        }
Example #19
0
        public IList <JpegHeader> ExtractHeaders()
        {
            // Extracts only the header (EXIF/XMP) data from the JPEG. This
            // method is useful if the JPEG is to be manipulated in any
            // way other than resizing (such as cropping), so that the metadata
            // can be easily re-added to the outputted JPEG. The separate call
            // is useful as loading the entire file just to pull the headers
            // is a very time consuming process

            bool haveMarker = false;
            bool foundJFIF  = false;

            var headers = new List <JpegHeader>();

            // Loop through until there are no more markers to read in, at
            // that point the headers have been fully extracted
            while (true)
            {
                if (DecodeProgress.Abort)
                {
                    return(null);
                }

                #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:

                    // We only want to extract the headers so they can be round tripped
                    // easily with the JPEG needs to be resized

                    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:
                    break;

                case JPEGMarker.DHT:
                    break;

                case JPEGMarker.DQT:
                    break;

                case JPEGMarker.SOS:
                    break;

                case JPEGMarker.DRI:
                    break;

                case JPEGMarker.DNL:
                    break;

                case JPEGMarker.EOI:
                    break;

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

            return(headers);
        }
Example #20
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);
        }
Example #21
0
		private void AddExifProperties (JpegHeader header)
		{
			Tiff.Header ifd = header.GetExifHeader ();
			if (ifd == null)
				return;
			//ifd.Dump ("foo"); // Uncomment to debug

			string str;
			Tiff.DirectoryEntry entry;

			// Add IFD 0 properies

			str = GetExifString (ifd.Directory, Tiff.TagId.Model);
			AddProperty (Beagle.Property.New ("exif:Model", str));

			str = GetExifString (ifd.Directory, Tiff.TagId.ImageDescription);
			AddProperty (Beagle.Property.New ("exif:ImageDescription", str));

			try {
				entry = ifd.Directory.Lookup (Tiff.TagId.DateTime);
				if (entry != null)
					// Assume datetime stored in the images are local times
					AddProperty (Beagle.Property.NewDate ("exif:DateTime", entry.ValueAsDate.ToUniversalTime ()));
			} catch (FormatException) {
				Logger.Log.Debug ("EXIF DateTime '{0}' is invalid.", GetExifString (ifd.Directory, Tiff.TagId.DateTime));
			} catch (ArgumentOutOfRangeException) {
				Logger.Log.Debug ("EXIF DateTime '{0}' is invalid.", GetExifString (ifd.Directory, Tiff.TagId.DateTime));
			}

			str = GetExifString (ifd.Directory, Tiff.TagId.Copyright);
			AddProperty (Beagle.Property.New ("dc:rights", str));

			// Add IFD 1 properties

			Tiff.SubdirectoryEntry subdir = (Tiff.SubdirectoryEntry) ifd.Directory.Lookup (Tiff.TagId.ExifIfdPointer);
			if (subdir == null)
				return;

			Tiff.ImageDirectory exif = subdir.Directory [0];
			if (exif == null)
				return;

			entry = exif.Lookup (Tiff.TagId.UserComment);
			if (entry != null)
				AddProperty (Beagle.Property.New ("exif:UserComment", entry.UserCommentValue));

			uint val = 0;
			entry = exif.Lookup (Tiff.TagId.PixelXDimension);
			if (entry != null)
				val = entry.ValueAsLong [0];
			if (val > 0) {
				Width = (int) val;
				AddProperty (Beagle.Property.NewUnsearched ("exif:PixelXDimension", val));
			}

			val = 0;
			entry = exif.Lookup (Tiff.TagId.PixelYDimension);
			if (entry != null)
				val = entry.ValueAsLong [0];
			if (val > 0) {
				Height = (int) val;
				AddProperty (Beagle.Property.NewUnsearched ("exif:PixelYDimension", val));
			}

			str = GetExifString (exif, Tiff.TagId.ISOSpeedRatings);
			AddProperty (Beagle.Property.NewUnsearched ("exif:ISOSpeedRatings", str));

			str = GetExifString (exif, Tiff.TagId.ShutterSpeedValue);
			AddProperty (Beagle.Property.NewUnsearched ("exif:ShutterSpeedValue", str));

			str = GetExifString (exif, Tiff.TagId.ExposureTime);
			if (! String.IsNullOrEmpty (str))
				AddProperty (Beagle.Property.NewUnsearched ("exif:ExposureTime", str + " sec."));

			double rational_val;

			rational_val = GetExifRational (exif, Tiff.TagId.FNumber);
			if (rational_val > 0)
				AddProperty (Beagle.Property.NewUnsearched ("exif:FNumber", String.Format ("f/{0}", rational_val)));

			rational_val = GetExifRational (exif, Tiff.TagId.ApertureValue);
			if (rational_val > 0)
				AddProperty (Beagle.Property.NewUnsearched ("exif:ApertureValue", rational_val));

			rational_val = GetExifRational (exif, Tiff.TagId.FocalLength);
			if (rational_val > 0)
				AddProperty (Beagle.Property.NewUnsearched ("exif:FocalLength", String.Format ("{0} mm", rational_val)));

			entry = exif.Lookup (Tiff.TagId.Flash);
			if (entry != null) {
				ushort flash = entry.ShortValue [0];
				AddProperty (Beagle.Property.NewUnsearched ("exif:Flash", GetFlashString (flash)));
			}
		}
Example #22
0
        private void AddJfifProperties(JpegHeader header)
        {
            string comment = header.GetJFIFComment();

            AddProperty(Beagle.Property.New("jfif:Comment", comment));
        }
Example #23
0
		private void AddXmpProperties (JpegHeader header)
		{
			XmpFile xmp = header.GetXmp ();
			if (xmp != null)
				AddXmpProperties (xmp);
		}
Example #24
0
		private void AddIptcProperties (JpegHeader header)
		{
			IptcFile iptc = header.GetIptc ();
			if (iptc == null)
				return;

			foreach (DataSet data in iptc.Sets) {
				switch (data.ID) {

				case DataSetID.ContentLocationName:
					AddProperty (Beagle.Property.New ("iptc:location", data.XmpObject));
					break;

				case DataSetID.CaptionAbstract:
					AddProperty (Beagle.Property.New ("iptc:caption", data.XmpObject));
					break;

				case DataSetID.Keywords:
					AddProperty (Beagle.Property.NewKeyword ("iptc:keyword", data.XmpObject));
					AddProperty (Beagle.Property.NewUnstored ("image:tag", data.XmpObject));
					break;

				default:
					// FIXME: Anything else to index ?
					//Log.Debug ("Ignoring {0} = [{1}]", data.ID, data.XmpObject);
					break;
				}
			}
		}
Example #25
0
		// FIXME: This is not particularly efficient
		protected override void PullImageProperties ()
		{
			JpegHeader header = new JpegHeader (Stream);

			AddJfifProperties (header);
			AddExifProperties (header);
			AddXmpProperties (header);
			AddIptcProperties (header);

			Finished (); // That's all folks...
		}
		private void SaveMetaData (System.IO.Stream input, System.IO.Stream output)
		{
			JpegHeader header = new JpegHeader (input);
			UpdateMeta ();
			
			// Console.WriteLine ("updated metadata");
			header.SetExif (this.ExifData);
			// Console.WriteLine ("set exif");
			if (xmp != null)
				header.SetXmp (xmp);
			// Console.WriteLine ("set xmp");
			header.Save (output);
			// Console.WriteLine ("saved");
		}
Example #27
0
		private void AddJfifProperties (JpegHeader header)
		{
			string comment = header.GetJFIFComment ();
			AddProperty (Beagle.Property.New ("jfif:Comment", comment));
		}