BitMiracle.LibJpeg.Classic.Internal.jpeg_marker_reader.get_sos C# (CSharp) Method

get_sos() private method

Process a SOS marker
private get_sos ( ) : bool
return bool
        private bool get_sos()
        {
            if (!m_cinfo.m_marker.m_saw_SOF)
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_SOF_BEFORE, "SOS");

            int length;
            if (!m_cinfo.m_src.GetTwoBytes(out length))
                return false;

            /* Number of components */
            int n;
            if (!m_cinfo.m_src.GetByte(out n))
                return false;

            m_cinfo.TRACEMS(1, J_MESSAGE_CODE.JTRC_SOS, n);

            if (length != (n * 2 + 6) || n > JpegConstants.MAX_COMPS_IN_SCAN ||
                (n == 0 && m_cinfo.m_progressive_mode))
            {
                /* pseudo SOS marker only allowed in progressive mode */
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_LENGTH);
            }

            m_cinfo.m_comps_in_scan = n;

            /* Collect the component-spec parameters */

            for (int i = 0; i < n; i++)
            {
                int c;
                if (!m_cinfo.m_src.GetByte(out c))
                    return false;

                /* Detect the case where component id's are not unique, and, if so, */
                /* create a fake component id using the same logic as in get_sof.   */
                /* Note:  This also ensures that all of the SOF components are      */
                /* referenced in the single scan case, which prevents access to     */
                /* uninitialized memory in later decoding stages. */
                for (int ci = 0; ci < i; ci++)
                {
                    jpeg_component_info componentInfo = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]];
                    if (c == componentInfo.Component_id)
                    {
                        componentInfo = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[0]];
                        c = componentInfo.Component_id;
                        for (ci = 1; ci < i; ci++)
                        {
                            componentInfo = m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]];
                            if (componentInfo.Component_id > c)
                                c = componentInfo.Component_id;
                        }
                        c++;
                        break;
                    }
                }

                bool idFound = false;
                int foundIndex = -1;
                for (int ci = 0; ci < m_cinfo.m_num_components; ci++)
                {
                    if (c == m_cinfo.Comp_info[ci].Component_id)
                    {
                        foundIndex = ci;
                        idFound = true;
                        break;
                    }
                }

                if (!idFound)
                    m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_COMPONENT_ID, c);

                m_cinfo.m_cur_comp_info[i] = foundIndex;

                if (!m_cinfo.m_src.GetByte(out c))
                    return false;

                m_cinfo.Comp_info[foundIndex].Dc_tbl_no = (c >> 4) & 15;
                m_cinfo.Comp_info[foundIndex].Ac_tbl_no = (c) & 15;

                m_cinfo.TRACEMS(1, J_MESSAGE_CODE.JTRC_SOS_COMPONENT,
                    m_cinfo.Comp_info[foundIndex].Component_id,
                    m_cinfo.Comp_info[foundIndex].Dc_tbl_no,
                    m_cinfo.Comp_info[foundIndex].Ac_tbl_no);
            }

            /* Collect the additional scan parameters Ss, Se, Ah/Al. */
            int temp;
            if (!m_cinfo.m_src.GetByte(out temp))
                return false;

            m_cinfo.m_Ss = temp;
            if (!m_cinfo.m_src.GetByte(out temp))
                return false;

            m_cinfo.m_Se = temp;
            if (!m_cinfo.m_src.GetByte(out temp))
                return false;

            m_cinfo.m_Ah = (temp >> 4) & 15;
            m_cinfo.m_Al = (temp) & 15;

            m_cinfo.TRACEMS(1, J_MESSAGE_CODE.JTRC_SOS_PARAMS, m_cinfo.m_Ss, m_cinfo.m_Se, m_cinfo.m_Ah, m_cinfo.m_Al);

            /* Prepare to scan data & restart markers */
            m_cinfo.m_marker.m_next_restart_num = 0;

            /* Count another (non-pseudo) SOS marker */
            if (n != 0)
                m_cinfo.m_input_scan_number++;

            return true;
        }