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;
}