예제 #1
0
        public void TestMarkerList()
        {
            jpeg_decompress_struct cinfo = new jpeg_decompress_struct();

            using (FileStream input = new FileStream(Tester.MapOpenPath("PARROTS.JPG"), FileMode.Open))
            {
                /* Specify data source for decompression */
                cinfo.jpeg_stdio_src(input);

                const int markerDataLengthLimit = 1000;
                cinfo.jpeg_save_markers((int)JPEG_MARKER.COM, markerDataLengthLimit);
                cinfo.jpeg_save_markers((int)JPEG_MARKER.APP0, markerDataLengthLimit);

                /* Read file header, set default decompression parameters */
                cinfo.jpeg_read_header(true);

                Assert.AreEqual(cinfo.Marker_list.Count, 3);

                int[] expectedMarkerType           = { (int)JPEG_MARKER.APP0, (int)JPEG_MARKER.APP0, (int)JPEG_MARKER.COM };
                int[] expectedMarkerOriginalLength = { 14, 3072, 10 };
                for (int i = 0; i < cinfo.Marker_list.Count; ++i)
                {
                    jpeg_marker_struct marker = cinfo.Marker_list[i];
                    Assert.IsNotNull(marker);
                    Assert.AreEqual(marker.Marker, expectedMarkerType[i]);
                    Assert.AreEqual(marker.OriginalLength, expectedMarkerOriginalLength[i]);
                    Assert.LessOrEqual(marker.Data.Length, markerDataLengthLimit);
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Reset marker processing state to begin a fresh datastream.
 /// </summary>
 public void reset_marker_reader()
 {
     m_cinfo.Comp_info           = null; /* until allocated by get_sof */
     m_cinfo.m_input_scan_number = 0;    /* no SOS seen yet */
     m_cinfo.m_unread_marker     = 0;    /* no pending marker */
     m_saw_SOI         = false;          /* set internal state too */
     m_saw_SOF         = false;
     m_discarded_bytes = 0;
     m_cur_marker      = null;
 }
예제 #3
0
 /// <summary>
 /// Reset marker processing state to begin a fresh datastream.
 /// </summary>
 public void reset_marker_reader()
 {
     m_cinfo.Comp_info = null;        /* until allocated by get_sof */
     m_cinfo.m_input_scan_number = 0;       /* no SOS seen yet */
     m_cinfo.m_unread_marker = 0;       /* no pending marker */
     m_saw_SOI = false;        /* set internal state too */
     m_saw_SOF = false;
     m_discarded_bytes = 0;
     m_cur_marker = null;
 }
        /// <summary>
        /// Save an APPn or COM marker into the marker list
        /// </summary>
        private static bool save_marker(jpeg_decompress_struct cinfo)
        {
            jpeg_marker_struct cur_marker = cinfo.m_marker.m_cur_marker;
    
            byte[] data = null;
            int length = 0;
            int bytes_read;
            int data_length;
            int dataOffset = 0;

            if (cur_marker == null)
            {
                /* begin reading a marker */
                if (!cinfo.m_src.GetTwoBytes(out length))
                    return false;

                length -= 2;
                if (length >= 0)
                {
                    /* watch out for bogus length word */
                    /* figure out how much we want to save */
                    int limit;
                    if (cinfo.m_unread_marker == (int)JPEG_MARKER.COM)
                        limit = cinfo.m_marker.m_length_limit_COM;
                    else
                        limit = cinfo.m_marker.m_length_limit_APPn[cinfo.m_unread_marker - (int)JPEG_MARKER.APP0];

                    if (length < limit)
                        limit = length;
                    
                    /* allocate and initialize the marker item */
                    cur_marker = new jpeg_marker_struct((byte)cinfo.m_unread_marker, length, limit);
                    
                    /* data area is just beyond the jpeg_marker_struct */
                    data = cur_marker.Data;
                    cinfo.m_marker.m_cur_marker = cur_marker;
                    cinfo.m_marker.m_bytes_read = 0;
                    bytes_read = 0;
                    data_length = limit;
                }
                else
                {
                    /* deal with bogus length word */
                    bytes_read = data_length = 0;
                    data = null;
                }
            }
            else
            {
                /* resume reading a marker */
                bytes_read = cinfo.m_marker.m_bytes_read;
                data_length = cur_marker.Data.Length;
                data = cur_marker.Data;
                dataOffset = bytes_read;
            }

            byte[] tempData = null;
            if (data_length != 0)
                tempData = new byte[data.Length];

            while (bytes_read < data_length)
            {
                /* move the restart point to here */
                cinfo.m_marker.m_bytes_read = bytes_read;

                /* If there's not at least one byte in buffer, suspend */
                if (!cinfo.m_src.MakeByteAvailable())
                    return false;

                /* Copy bytes with reasonable rapidity */
                int read = cinfo.m_src.GetBytes(tempData, data_length - bytes_read);
                Buffer.BlockCopy(tempData, 0, data, dataOffset, data_length - bytes_read);
                bytes_read += read;
            }

            /* Done reading what we want to read */
            if (cur_marker != null)
            {
                /* will be null if bogus length word */
                /* Add new marker to end of list */
                cinfo.m_marker_list.Add(cur_marker);

                /* Reset pointer & calc remaining data length */
                data = cur_marker.Data;
                dataOffset = 0;
                length = cur_marker.OriginalLength - data_length;
            }

            /* Reset to initial state for next marker */
            cinfo.m_marker.m_cur_marker = null;

            JPEG_MARKER currentMarker = (JPEG_MARKER)cinfo.m_unread_marker;
            if (data_length != 0 && (currentMarker == JPEG_MARKER.APP0 || currentMarker == JPEG_MARKER.APP14))
            {
                tempData = new byte[data.Length];
                Buffer.BlockCopy(data, dataOffset, tempData, 0, data.Length - dataOffset);
            }

            /* Process the marker if interesting; else just make a generic trace msg */
            switch ((JPEG_MARKER)cinfo.m_unread_marker)
            {
                case JPEG_MARKER.APP0:
                    examine_app0(cinfo, tempData, data_length, length);
                    break;
                case JPEG_MARKER.APP14:
                    examine_app14(cinfo, tempData, data_length, length);
                    break;
                default:
                    cinfo.TRACEMS(1, J_MESSAGE_CODE.JTRC_MISC_MARKER, cinfo.m_unread_marker, data_length + length);
                    break;
            }

            /* skip any remaining data -- could be lots */
            if (length > 0)
                cinfo.m_src.skip_input_data(length);

            return true;
        }
예제 #5
0
        /// <summary>
        /// Save an APPn or COM marker into the marker list
        /// </summary>
        private static bool save_marker(jpeg_decompress_struct cinfo)
        {
            jpeg_marker_struct cur_marker = cinfo.m_marker.m_cur_marker;

            byte[] data   = null;
            int    length = 0;
            int    bytes_read;
            int    data_length;
            int    dataOffset = 0;

            if (cur_marker == null)
            {
                /* begin reading a marker */
                if (!cinfo.m_src.GetTwoBytes(out length))
                {
                    return(false);
                }

                length -= 2;
                if (length >= 0)
                {
                    /* watch out for bogus length word */
                    /* figure out how much we want to save */
                    int limit;
                    if (cinfo.m_unread_marker == (int)JPEG_MARKER.COM)
                    {
                        limit = cinfo.m_marker.m_length_limit_COM;
                    }
                    else
                    {
                        limit = cinfo.m_marker.m_length_limit_APPn[cinfo.m_unread_marker - (int)JPEG_MARKER.APP0];
                    }

                    if (length < limit)
                    {
                        limit = length;
                    }

                    /* allocate and initialize the marker item */
                    cur_marker = new jpeg_marker_struct((byte)cinfo.m_unread_marker, length, limit);

                    /* data area is just beyond the jpeg_marker_struct */
                    data = cur_marker.Data;
                    cinfo.m_marker.m_cur_marker = cur_marker;
                    cinfo.m_marker.m_bytes_read = 0;
                    bytes_read  = 0;
                    data_length = limit;
                }
                else
                {
                    /* deal with bogus length word */
                    bytes_read = data_length = 0;
                    data       = null;
                }
            }
            else
            {
                /* resume reading a marker */
                bytes_read  = cinfo.m_marker.m_bytes_read;
                data_length = cur_marker.Data.Length;
                data        = cur_marker.Data;
                dataOffset  = bytes_read;
            }

            byte[] tempData = null;
            if (data_length != 0)
            {
                tempData = new byte[data.Length];
            }

            while (bytes_read < data_length)
            {
                /* move the restart point to here */
                cinfo.m_marker.m_bytes_read = bytes_read;

                /* If there's not at least one byte in buffer, suspend */
                if (!cinfo.m_src.MakeByteAvailable())
                {
                    return(false);
                }

                /* Copy bytes with reasonable rapidity */
                int read = cinfo.m_src.GetBytes(tempData, data_length - bytes_read);
                Buffer.BlockCopy(tempData, 0, data, dataOffset, read);
                bytes_read += read;
                dataOffset += read;
            }

            /* Done reading what we want to read */
            if (cur_marker != null)
            {
                /* will be null if bogus length word */
                /* Add new marker to end of list */
                cinfo.m_marker_list.Add(cur_marker);

                /* Reset pointer & calc remaining data length */
                data       = cur_marker.Data;
                dataOffset = 0;
                length     = cur_marker.OriginalLength - data_length;
            }

            /* Reset to initial state for next marker */
            cinfo.m_marker.m_cur_marker = null;

            JPEG_MARKER currentMarker = (JPEG_MARKER)cinfo.m_unread_marker;

            if (data_length != 0 && (currentMarker == JPEG_MARKER.APP0 || currentMarker == JPEG_MARKER.APP14))
            {
                tempData = new byte[data.Length];
                Buffer.BlockCopy(data, dataOffset, tempData, 0, data.Length - dataOffset);
            }

            /* Process the marker if interesting; else just make a generic trace msg */
            switch ((JPEG_MARKER)cinfo.m_unread_marker)
            {
            case JPEG_MARKER.APP0:
                examine_app0(cinfo, tempData, data_length, length);
                break;

            case JPEG_MARKER.APP14:
                examine_app14(cinfo, tempData, data_length, length);
                break;

            default:
                cinfo.TRACEMS(1, J_MESSAGE_CODE.JTRC_MISC_MARKER, cinfo.m_unread_marker, data_length + length);
                break;
            }

            /* skip any remaining data -- could be lots */
            if (length > 0)
            {
                cinfo.m_src.skip_input_data(length);
            }

            return(true);
        }
예제 #6
0
		// Save an APPn or COM marker into the marker list
		static bool save_marker(jpeg_decompress cinfo)
		{
			my_marker_reader marker=(my_marker_reader)cinfo.marker;
			jpeg_marker_struct cur_marker=marker.cur_marker;
			uint bytes_read, data_length;
			byte[] data;
			jpeg_source_mgr datasrc=cinfo.src;
			byte[] input_bytes=datasrc.input_bytes;
			int next_input_byte=datasrc.next_input_byte;
			uint bytes_in_buffer=datasrc.bytes_in_buffer;

			int length=0;
			uint data_ind=0;
			if(cur_marker==null)
			{
				// begin reading a marker
				if(bytes_in_buffer==0)
				{
					if(!datasrc.fill_input_buffer(cinfo)) return false;
					input_bytes=datasrc.input_bytes;
					next_input_byte=datasrc.next_input_byte;
					bytes_in_buffer=datasrc.bytes_in_buffer;
				}
				bytes_in_buffer--;
				length=((int)input_bytes[next_input_byte++])<<8;
				if(bytes_in_buffer==0)
				{
					if(!datasrc.fill_input_buffer(cinfo)) return false;
					input_bytes=datasrc.input_bytes;
					next_input_byte=datasrc.next_input_byte;
					bytes_in_buffer=datasrc.bytes_in_buffer;
				}
				bytes_in_buffer--;
				length+=input_bytes[next_input_byte++];

				length-=2;
				if(length>=0)
				{	// watch out for bogus length word
					// figure out how much we want to save
					uint limit;
					if(cinfo.unread_marker==(int)JPEG_MARKER.M_COM) limit=marker.length_limit_COM;
					else limit=marker.length_limit_APPn[cinfo.unread_marker-(int)JPEG_MARKER.M_APP0];

					if((uint)length<limit) limit=(uint)length;

					// allocate and initialize the marker item
					try
					{
						cur_marker=new jpeg_marker_struct();
						cur_marker.data=new byte[limit];
					}
					catch
					{
						ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
					}
					cur_marker.next=null;
					cur_marker.marker=(byte)cinfo.unread_marker;
					cur_marker.original_length=(uint)length;
					cur_marker.data_length=limit;

					// data area is just beyond the jpeg_marker_struct
					data=cur_marker.data;
					marker.cur_marker=cur_marker;
					marker.bytes_read=0;
					bytes_read=0;
					data_length=limit;
				}
				else
				{
					// deal with bogus length word
					bytes_read=data_length=0;
					data=null;
				}
			}
			else
			{
				// resume reading a marker
				bytes_read=marker.bytes_read;
				data_length=cur_marker.data_length;
				data=cur_marker.data;
				data_ind=bytes_read;
			}

			while(bytes_read<data_length)
			{
				// move the restart point to here
				datasrc.input_bytes=input_bytes;
				datasrc.next_input_byte=next_input_byte;
				datasrc.bytes_in_buffer=bytes_in_buffer;

				marker.bytes_read=bytes_read;

				// If there's not at least one byte in buffer, suspend
				if(bytes_in_buffer==0)
				{
					if(!datasrc.fill_input_buffer(cinfo)) return false;
					input_bytes=datasrc.input_bytes;
					next_input_byte=datasrc.next_input_byte;
					bytes_in_buffer=datasrc.bytes_in_buffer;
				}

				// Copy bytes with reasonable rapidity
				while(bytes_read<data_length&&bytes_in_buffer>0)
				{
					data[data_ind++]=input_bytes[next_input_byte++];
					bytes_in_buffer--;
					bytes_read++;
				}
			}

			// Done reading what we want to read
			if(cur_marker!=null)
			{	// will be null if bogus length word
				// Add new marker to end of list
				if(cinfo.marker_list==null)
				{
					cinfo.marker_list=cur_marker;
				}
				else
				{
					jpeg_marker_struct prev=cinfo.marker_list;
					while(prev.next!=null) prev=prev.next;
					prev.next=cur_marker;
				}

				// Reset pointer & calc remaining data length
				data=cur_marker.data;
				length=(int)(cur_marker.original_length-data_length);
			}
			// Reset to initial state for next marker
			marker.cur_marker=null;

			// Process the marker if interesting; else just make a generic trace msg
			switch(cinfo.unread_marker)
			{
				case (int)JPEG_MARKER.M_APP0: examine_app0(cinfo, data, data_length, length); break;
				case (int)JPEG_MARKER.M_APP1:
					if(data_length>=14&&data[0]==0x45&&data[1]==0x78&&data[2]==0x69&&data[3]==0x66&&data[4]==0&&data[5]==0)
					{ // Exif found
						EXIF exif=new EXIF();
						if(exif.Scan(data, 6)) cinfo.exif=exif;
					}
					break;
				case (int)JPEG_MARKER.M_APP14: examine_app14(cinfo, data, data_length, length); break;
				default: TRACEMS2(cinfo, 1, J_MESSAGE_CODE.JTRC_MISC_MARKER, cinfo.unread_marker, (int)(data_length+length)); break;
			}

			// skip any remaining data -- could be lots
			// do before skip_input_data
			datasrc.input_bytes=input_bytes;
			datasrc.next_input_byte=next_input_byte;
			datasrc.bytes_in_buffer=bytes_in_buffer;

			if(length>0) cinfo.src.skip_input_data(cinfo, (int)length);

			return true;
		}