//////////////////////////////////////////////////////////////////////////
        // Main entry points for decompression
        /// <summary>
        /// Decompression initialization.
        /// </summary>
        /// <returns>Returns <c>false</c> if suspended. The return value need be inspected 
        /// only if a suspending data source is used.
        /// </returns>
        /// <remarks><see cref="jpeg_decompress_struct.jpeg_read_header">jpeg_read_header</see> must be completed before calling this.<br/>
        /// 
        /// If a multipass operating mode was selected, this will do all but the last pass, and thus may take a great deal of time.
        /// </remarks>
        /// <seealso cref="jpeg_decompress_struct.jpeg_finish_decompress"/>
        /// <seealso href="9d052723-a7f9-42de-8747-0bd9896f8157.htm" target="_self">Decompression details</seealso>
        public bool jpeg_start_decompress()
        {
            if (m_global_state == JpegState.DSTATE_READY)
            {
                /* First call: initialize master control, select active modules */
                m_master = new jpeg_decomp_master(this);
                if (m_buffered_image)
                {
                    /* No more work here; expecting jpeg_start_output next */
                    m_global_state = JpegState.DSTATE_BUFIMAGE;
                    return true;
                }
                m_global_state = JpegState.DSTATE_PRELOAD;
            }

            if (m_global_state == JpegState.DSTATE_PRELOAD)
            {
                /* If file has multiple scans, absorb them all into the coef buffer */
                if (m_inputctl.HasMultipleScans())
                {
                    for ( ; ; )
                    {
                        ReadResult retcode;
                        /* Call progress monitor hook if present */
                        if (m_progress != null)
                            m_progress.Updated();

                        /* Absorb some more input */
                        retcode = m_inputctl.consume_input();
                        if (retcode == ReadResult.JPEG_SUSPENDED)
                            return false;

                        if (retcode == ReadResult.JPEG_REACHED_EOI)
                            break;

                        /* Advance progress counter if appropriate */
                        if (m_progress != null && (retcode == ReadResult.JPEG_ROW_COMPLETED || retcode == ReadResult.JPEG_REACHED_SOS))
                        {
                            m_progress.Pass_counter++;
                            if (m_progress.Pass_counter >= m_progress.Pass_limit)
                            {
                                /* underestimated number of scans; ratchet up one scan */
                                m_progress.Pass_limit += m_total_iMCU_rows;
                            }
                        }
                    }
                }

                m_output_scan_number = m_input_scan_number;
            }
            else if (m_global_state != JpegState.DSTATE_PRESCAN)
                ERREXIT(J_MESSAGE_CODE.JERR_BAD_STATE, (int)m_global_state);

            /* Perform any dummy output passes, and set up for the final pass */
            return output_pass_setup();
        }