Пример #1
0
        public bool Open(Stream fs)
        {
            try
            {
                var intSizeArr = new byte[4];
                var shortSizeArr = new byte[2];
                short shortSize;
                int intSize;
                long length;

                //Read JPG SOF (FF,D8)
                length = fs.Read(shortSizeArr, 0, 2);
                if (length != 2 || shortSizeArr[0] != 0xFF || shortSizeArr[1] != 0xD8)
                {    
                    errorMessage = "File has no 0xFFD8 on start!";
                    return false;
                }

                //READ First SOF 0:APP0:Jfif:0xFFE0 / 1:APP1:Exif:0xFFE1
                length = fs.Read(shortSizeArr, 0, 2);
                if (shortSizeArr[0] == 0xFF && shortSizeArr[1] == 0xE0)
                {   //If  SOF0 found then skip it
                    length = fs.Read(shortSizeArr, 0, 2);
                    shortSize = ByteArrToShortBE(shortSizeArr);
                    fs.Seek(shortSize - 2, SeekOrigin.Current);
                    length = fs.Read(shortSizeArr, 0, 2); //Read next SOF#
                }
                if (shortSizeArr[0] != 0xFF || shortSizeArr[1] != 0xE1) //suppose to be next
                {
                    errorMessage = "No Exif information (No APP1)";
                    return false;
                }
                //Skip over APP1
                length = fs.Read(shortSizeArr, 0, 2);
                shortSize = ByteArrToShortBE(shortSizeArr);
                fs.Seek(shortSize - 2, SeekOrigin.Current);

                //Read next SOF 2:APP2:MPE:0xFFE2
                length = fs.Read(shortSizeArr, 0, 2);
                if (length != 2 || shortSizeArr[0] != 0xFF || shortSizeArr[1] != 0xE2)
                {
                    errorMessage = "File has no 0xFFE2 on start!";
                    return false;
                }

                fs.Seek(2, SeekOrigin.Current); //Skip over APP2 length field
                //Read MP Magic
                length = fs.Read(intSizeArr, 0, 4);
                if (length != 4)
                {
                    errorMessage = "No MP Magic (MPF.)!";
                    return false;
                }
                if (!IsMPFMagic(intSizeArr))
                {
                    errorMessage = "Wrong MP Magic (MPF.)!";
                    return false;
                }

                var fromSOO = 0;
                //READ THE MP Header Endianess
                length = fs.Read(intSizeArr, 0, 4);
                if (length != 4)
                {
                    errorMessage = "No APP2 Endianess!";
                    return false;
                }
                fromSOO += 4;
                var endianess = 0;
                if (intSizeArr[0] == 0x49 && intSizeArr[1] == 0x49 && intSizeArr[2] == 0x2A && intSizeArr[3] == 0x00)
                    endianess = 1; // LE
                else if (intSizeArr[0] == 0x4D && intSizeArr[1] == 0x4D && intSizeArr[2] == 0x00 && intSizeArr[3] == 0x2A)
                    endianess = 2; // BE
                if (endianess == 0)
                {
                    errorMessage = "Wrong APP2 Endianess!";
                    return false;
                } 
                //Read First IFD Offset
                length = fs.Read(intSizeArr, 0, 4);
                if (length != 4)
                {
                    errorMessage = "No First IFD Offset!";
                    return false;
                }
                
                fromSOO += 4;
                intSize = (endianess == 1 ? BitConverter.ToInt32(intSizeArr, 0) : ByteArrToIntBE(intSizeArr));

                if (intSize - fromSOO > 0) //Goto Offset
                    fs.Seek(intSize - fromSOO, SeekOrigin.Current);
                // Skip MP Entry: Count[2], Version[12], No[12], No*16[12], Attr[4], Size[4]
                fs.Seek(46, SeekOrigin.Current);

                // Read 1st Image Size
                length = fs.Read(intSizeArr, 0, 4);
                if (length != 4)
                {
                    errorMessage = "No Image Size!";
                    return false;
                }

                intSize = (endianess == 1 ? BitConverter.ToInt32(intSizeArr, 0) : ByteArrToIntBE(intSizeArr));

                fs.Seek(0, SeekOrigin.Begin);

                LeftImageBytes = new byte[intSize];
                fs.Read(LeftImageBytes, 0, intSize);
                LeftImage = ByteArrayToImage(LeftImageBytes);

                // Go to the start of the next file (skip junk)
                //int space = 1;
                var found = false;
                while (!found)
                {
                    if (fs.ReadByte() == 0xFF)
                    {
                        if (fs.ReadByte() == 0xD8)
                        {
                            found = true;
                        }
                    }
                }

                fs.Seek(-2, SeekOrigin.Current);
                intSize = 0;
                RightImageBytes = new byte[fs.Length - intSize - 1];
                fs.Read(RightImageBytes, 0, (int)(fs.Length - intSize - 1));
                RightImage = ByteArrayToImage(RightImageBytes);

                fs.Close();
                fs = null;

                var propItems = LeftImage.PropertyItems;
                var nintendo = false;
                foreach (var propItem in propItems)
                {
                    if (propItem.Id == 0x010F) // Manufacturer
                        nintendo = Encoding.UTF8.GetString(propItem.Value).Equals("Nintendo\0");
                    else if ((propItem.Id == 0x927C) && nintendo) // MakerNote
                    {
                        var memStream = new MemoryStream(propItem.Value);
                        var ifdCount = (ushort)(memStream.ReadByte() << 8);
                        ifdCount += (byte)memStream.ReadByte();
                        _ifds = new IFD[ifdCount];
                        for (var i=0;i<_ifds.Length;i++)
                            _ifds[i] = MarshalUtil.ReadStructBE<IFD>(memStream) ;
                        //read the zero
                        //ifdCount = (ushort)(memStream.ReadByte() << 8);
                        //ifdCount += (byte)memStream.ReadByte();
                        //jump over the first ifd
                        memStream.Seek(4, SeekOrigin.Current);
                        _firstIFDData = new byte[_ifds[0].CountValue];
                        memStream.Read(_firstIFDData, 0, _firstIFDData.Length);
                        _nintendoNote = MarshalUtil.ReadStruct<NintendoNote>(memStream);
                        memStream.Close();
                        break;
                    }
                }
                var px = _nintendoNote.Parallax == 0 ? -10 : _nintendoNote.Parallax;

                //make images for animation
                LeftLaxxedImage = new Bitmap(LeftImage.Width + (int)px, LeftImage.Height);
                RightLaxxedImage = new Bitmap(RightImage.Width + (int)px, RightImage.Height);
                var g = Graphics.FromImage(LeftLaxxedImage);
                g.DrawImage(LeftImage, new Rectangle(0, 0, RightImage.Width + (int)px, RightImage.Height), new Rectangle(0, 0, LeftImage.Width + (int)px, LeftImage.Height), GraphicsUnit.Pixel);
                g.Dispose();
                g = Graphics.FromImage(RightLaxxedImage);
                g.DrawImage(RightImage, new Rectangle(0, 0, RightImage.Width + (int)px, RightImage.Height), new Rectangle(-(int)px, 0, RightImage.Width + (int)px, RightImage.Height), GraphicsUnit.Pixel);
                g.Dispose();

                //make anaglyph

                AnaglyphImage = Anaglyph.MakeAnaglyph(LeftImage, RightImage, (new Anaglyph()).HalfColorAnaglyph, (int)px);

                return true;
            }
            catch (Exception ex)
            {
                errorMessage = "Error in Opening file:" + Environment.NewLine + ex.Message;
                return false;
            }
            finally
            {
                if (fs != null)
                    fs.Close();
            }
        }
Пример #2
0
        public bool Open(Stream fs)
        {
            try
            {
                var   intSizeArr   = new byte[4];
                var   shortSizeArr = new byte[2];
                short shortSize;
                int   intSize;
                long  length;

                //Read JPG SOF (FF,D8)
                length = fs.Read(shortSizeArr, 0, 2);
                if (length != 2 || shortSizeArr[0] != 0xFF || shortSizeArr[1] != 0xD8)
                {
                    errorMessage = "File has no 0xFFD8 on start!";
                    return(false);
                }

                //READ First SOF 0:APP0:Jfif:0xFFE0 / 1:APP1:Exif:0xFFE1
                length = fs.Read(shortSizeArr, 0, 2);
                if (shortSizeArr[0] == 0xFF && shortSizeArr[1] == 0xE0)
                {   //If  SOF0 found then skip it
                    length    = fs.Read(shortSizeArr, 0, 2);
                    shortSize = ByteArrToShortBE(shortSizeArr);
                    fs.Seek(shortSize - 2, SeekOrigin.Current);
                    length = fs.Read(shortSizeArr, 0, 2);               //Read next SOF#
                }
                if (shortSizeArr[0] != 0xFF || shortSizeArr[1] != 0xE1) //suppose to be next
                {
                    errorMessage = "No Exif information (No APP1)";
                    return(false);
                }
                //Skip over APP1
                length    = fs.Read(shortSizeArr, 0, 2);
                shortSize = ByteArrToShortBE(shortSizeArr);
                fs.Seek(shortSize - 2, SeekOrigin.Current);

                //Read next SOF 2:APP2:MPE:0xFFE2
                length = fs.Read(shortSizeArr, 0, 2);
                if (length != 2 || shortSizeArr[0] != 0xFF || shortSizeArr[1] != 0xE2)
                {
                    errorMessage = "File has no 0xFFE2 on start!";
                    return(false);
                }

                fs.Seek(2, SeekOrigin.Current); //Skip over APP2 length field
                //Read MP Magic
                length = fs.Read(intSizeArr, 0, 4);
                if (length != 4)
                {
                    errorMessage = "No MP Magic (MPF.)!";
                    return(false);
                }
                if (!IsMPFMagic(intSizeArr))
                {
                    errorMessage = "Wrong MP Magic (MPF.)!";
                    return(false);
                }

                var fromSOO = 0;
                //READ THE MP Header Endianess
                length = fs.Read(intSizeArr, 0, 4);
                if (length != 4)
                {
                    errorMessage = "No APP2 Endianess!";
                    return(false);
                }
                fromSOO += 4;
                var endianess = 0;
                if (intSizeArr[0] == 0x49 && intSizeArr[1] == 0x49 && intSizeArr[2] == 0x2A && intSizeArr[3] == 0x00)
                {
                    endianess = 1; // LE
                }
                else if (intSizeArr[0] == 0x4D && intSizeArr[1] == 0x4D && intSizeArr[2] == 0x00 && intSizeArr[3] == 0x2A)
                {
                    endianess = 2; // BE
                }
                if (endianess == 0)
                {
                    errorMessage = "Wrong APP2 Endianess!";
                    return(false);
                }
                //Read First IFD Offset
                length = fs.Read(intSizeArr, 0, 4);
                if (length != 4)
                {
                    errorMessage = "No First IFD Offset!";
                    return(false);
                }

                fromSOO += 4;
                intSize  = (endianess == 1 ? BitConverter.ToInt32(intSizeArr, 0) : ByteArrToIntBE(intSizeArr));

                if (intSize - fromSOO > 0) //Goto Offset
                {
                    fs.Seek(intSize - fromSOO, SeekOrigin.Current);
                }
                // Skip MP Entry: Count[2], Version[12], No[12], No*16[12], Attr[4], Size[4]
                fs.Seek(46, SeekOrigin.Current);

                // Read 1st Image Size
                length = fs.Read(intSizeArr, 0, 4);
                if (length != 4)
                {
                    errorMessage = "No Image Size!";
                    return(false);
                }

                intSize = (endianess == 1 ? BitConverter.ToInt32(intSizeArr, 0) : ByteArrToIntBE(intSizeArr));

                fs.Seek(0, SeekOrigin.Begin);

                LeftImageBytes = new byte[intSize];
                fs.Read(LeftImageBytes, 0, intSize);
                LeftImage = ByteArrayToImage(LeftImageBytes);

                // Go to the start of the next file (skip junk)
                //int space = 1;
                var found = false;
                while (!found)
                {
                    if (fs.ReadByte() == 0xFF)
                    {
                        if (fs.ReadByte() == 0xD8)
                        {
                            found = true;
                        }
                    }
                }

                fs.Seek(-2, SeekOrigin.Current);
                intSize         = 0;
                RightImageBytes = new byte[fs.Length - intSize - 1];
                fs.Read(RightImageBytes, 0, (int)(fs.Length - intSize - 1));
                RightImage = ByteArrayToImage(RightImageBytes);

                fs.Close();
                fs = null;

                var propItems = LeftImage.PropertyItems;
                var nintendo  = false;
                foreach (var propItem in propItems)
                {
                    if (propItem.Id == 0x010F) // Manufacturer
                    {
                        nintendo = Encoding.UTF8.GetString(propItem.Value).Equals("Nintendo\0");
                    }
                    else if ((propItem.Id == 0x927C) && nintendo) // MakerNote
                    {
                        var memStream = new MemoryStream(propItem.Value);
                        var ifdCount  = (ushort)(memStream.ReadByte() << 8);
                        ifdCount += (byte)memStream.ReadByte();
                        _ifds     = new IFD[ifdCount];
                        for (var i = 0; i < _ifds.Length; i++)
                        {
                            _ifds[i] = MarshalUtil.ReadStructBE <IFD>(memStream);
                        }
                        //read the zero
                        //ifdCount = (ushort)(memStream.ReadByte() << 8);
                        //ifdCount += (byte)memStream.ReadByte();
                        //jump over the first ifd
                        memStream.Seek(4, SeekOrigin.Current);
                        _firstIFDData = new byte[_ifds[0].CountValue];
                        memStream.Read(_firstIFDData, 0, _firstIFDData.Length);
                        _nintendoNote = MarshalUtil.ReadStruct <NintendoNote>(memStream);
                        memStream.Close();
                        break;
                    }
                }
                var px = _nintendoNote.Parallax == 0 ? -10 : _nintendoNote.Parallax;

                //make images for animation
                LeftLaxxedImage  = new Bitmap(LeftImage.Width + (int)px, LeftImage.Height);
                RightLaxxedImage = new Bitmap(RightImage.Width + (int)px, RightImage.Height);
                var g = Graphics.FromImage(LeftLaxxedImage);
                g.DrawImage(LeftImage, new Rectangle(0, 0, RightImage.Width + (int)px, RightImage.Height), new Rectangle(0, 0, LeftImage.Width + (int)px, LeftImage.Height), GraphicsUnit.Pixel);
                g.Dispose();
                g = Graphics.FromImage(RightLaxxedImage);
                g.DrawImage(RightImage, new Rectangle(0, 0, RightImage.Width + (int)px, RightImage.Height), new Rectangle(-(int)px, 0, RightImage.Width + (int)px, RightImage.Height), GraphicsUnit.Pixel);
                g.Dispose();

                //make anaglyph

                AnaglyphImage = Anaglyph.MakeAnaglyph(LeftImage, RightImage, (new Anaglyph()).HalfColorAnaglyph, (int)px);

                return(true);
            }
            catch (Exception ex)
            {
                errorMessage = "Error in Opening file:" + Environment.NewLine + ex.Message;
                return(false);
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }