// Set up the scan parameters for the current scan private void select_scan_parameters() { if (m_cinfo.m_scan_info != null) { /* Prepare for current scan --- the script is already validated */ jpeg_scan_info scanInfo = m_cinfo.m_scan_info[m_scan_number]; m_cinfo.m_comps_in_scan = scanInfo.comps_in_scan; for (int ci = 0; ci < scanInfo.comps_in_scan; ci++) { m_cinfo.m_cur_comp_info[ci] = scanInfo.component_index[ci]; } if (m_cinfo.m_progressive_mode) { m_cinfo.m_Ss = scanInfo.Ss; m_cinfo.m_Se = scanInfo.Se; m_cinfo.m_Ah = scanInfo.Ah; m_cinfo.m_Al = scanInfo.Al; return; } } else { /* Prepare for single sequential-JPEG scan containing all components */ if (m_cinfo.m_num_components > JpegConstants.MAX_COMPS_IN_SCAN) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_COMPONENT_COUNT, m_cinfo.m_num_components, JpegConstants.MAX_COMPS_IN_SCAN); } m_cinfo.m_comps_in_scan = m_cinfo.m_num_components; for (int ci = 0; ci < m_cinfo.m_num_components; ci++) { m_cinfo.m_cur_comp_info[ci] = ci; } } m_cinfo.m_Ss = 0; m_cinfo.m_Se = m_cinfo.block_size * m_cinfo.block_size - 1; m_cinfo.m_Ah = 0; m_cinfo.m_Al = 0; }
/// <summary> /// Generates a default scan script for writing a progressive-JPEG file. /// </summary> /// <remarks>This is the recommended method of creating a progressive file, unless you want /// to make a custom scan sequence. You must ensure that the JPEG color space is /// set correctly before calling this routine.</remarks> /// <seealso href="ce3f6712-3633-4a58-af07-626a4fba9ae4.htm" target="_self">Compression parameter selection</seealso> public void jpeg_simple_progression() { /* Safety check to ensure start_compress not called yet. */ if (m_global_state != JpegState.CSTATE_START) ERREXIT(J_MESSAGE_CODE.JERR_BAD_STATE, (int)m_global_state); /* Figure space needed for script. Calculation must match code below! */ int nscans; if (m_num_components == 3 && m_jpeg_color_space == J_COLOR_SPACE.JCS_YCbCr) { /* Custom script for YCbCr color images. */ nscans = 10; } else { /* All-purpose script for other color spaces. */ if (m_num_components > JpegConstants.MAX_COMPS_IN_SCAN) { /* 2 DC + 4 AC scans per component */ nscans = 6 * m_num_components; } else { /* 2 DC scans; 4 AC scans per component */ nscans = 2 + 4 * m_num_components; } } /* Allocate space for script. * We need to put it in the permanent pool in case the application performs * multiple compressions without changing the settings. To avoid a memory * leak if jpeg_simple_progression is called repeatedly for the same JPEG * object, we try to re-use previously allocated space, and we allocate * enough space to handle YCbCr even if initially asked for grayscale. */ if (m_script_space == null || m_script_space_size < nscans) { m_script_space_size = Math.Max(nscans, 10); m_script_space = new jpeg_scan_info[m_script_space_size]; for (int i = 0; i < m_script_space_size; i++) m_script_space[i] = new jpeg_scan_info(); } m_scan_info = m_script_space; m_num_scans = nscans; int scanIndex = 0; if (m_num_components == 3 && m_jpeg_color_space == J_COLOR_SPACE.JCS_YCbCr) { /* Custom script for YCbCr color images. */ /* Initial DC scan */ fill_dc_scans(ref scanIndex, m_num_components, 0, 1); /* Initial AC scan: get some luma data out in a hurry */ fill_a_scan(ref scanIndex, 0, 1, 5, 0, 2); /* Chroma data is too small to be worth expending many scans on */ fill_a_scan(ref scanIndex, 2, 1, 63, 0, 1); fill_a_scan(ref scanIndex, 1, 1, 63, 0, 1); /* Complete spectral selection for luma AC */ fill_a_scan(ref scanIndex, 0, 6, 63, 0, 2); /* Refine next bit of luma AC */ fill_a_scan(ref scanIndex, 0, 1, 63, 2, 1); /* Finish DC successive approximation */ fill_dc_scans(ref scanIndex, m_num_components, 1, 0); /* Finish AC successive approximation */ fill_a_scan(ref scanIndex, 2, 1, 63, 1, 0); fill_a_scan(ref scanIndex, 1, 1, 63, 1, 0); /* Luma bottom bit comes last since it's usually largest scan */ fill_a_scan(ref scanIndex, 0, 1, 63, 1, 0); } else { /* All-purpose script for other color spaces. */ /* Successive approximation first pass */ fill_dc_scans(ref scanIndex, m_num_components, 0, 1); fill_scans(ref scanIndex, m_num_components, 1, 5, 0, 2); fill_scans(ref scanIndex, m_num_components, 6, 63, 0, 2); /* Successive approximation second pass */ fill_scans(ref scanIndex, m_num_components, 1, 63, 2, 1); /* Successive approximation final pass */ fill_dc_scans(ref scanIndex, m_num_components, 1, 0); fill_scans(ref scanIndex, m_num_components, 1, 63, 1, 0); } }