public JpegDCoefController(JpegDecompressStruct cinfo, bool need_full_buffer) { m_cinfo = cinfo; /* Create the coefficient buffer. */ if (need_full_buffer) { /* Allocate a full-image virtual array for each component, */ /* padded to a multiple of samp_factor DCT blocks in each direction. */ /* Note we ask for a pre-zeroed array. */ for (var ci = 0; ci < cinfo.numComponents; ci++) { m_whole_image[ci] = JpegCommonStruct.CreateBlocksArray( JpegUtils.jround_up(cinfo.CompInfo[ci].Width_in_blocks, cinfo.CompInfo[ci].H_samp_factor), JpegUtils.jround_up(cinfo.CompInfo[ci].height_in_blocks, cinfo.CompInfo[ci].V_samp_factor)); m_whole_image[ci].ErrorProcessor = cinfo; } m_useDummyConsumeData = false; m_decompressor = DecompressorType.Ordinary; m_coef_arrays = m_whole_image; /* link to virtual arrays */ } else { /* We only need a single-MCU buffer. */ for (var i = 0; i < JpegConstants.D_MAX_BLOCKS_IN_MCU; i++) { m_MCU_buffer[i] = new JBlock(); } m_useDummyConsumeData = true; m_decompressor = DecompressorType.OnePass; m_coef_arrays = null; /* flag for no virtual arrays */ } }
/// <summary> /// Create the colormap. /// </summary> private void CreateColormap() { /* Select number of colors for each component */ var total_colors = SelectNColors(m_Ncolors); /* Report selected color counts */ if (m_cinfo.outColorComponents == 3) { m_cinfo.TraceMS(1, JMessageCode.JTRC_QUANT_3_NCOLORS, total_colors, m_Ncolors[0], m_Ncolors[1], m_Ncolors[2]); } else { m_cinfo.TraceMS(1, JMessageCode.JTRC_QUANT_NCOLORS, total_colors); } /* Allocate and fill in the colormap. */ /* The colors are ordered in the map in standard row-major order, */ /* i.e. rightmost (highest-indexed) color changes most rapidly. */ var colormap = JpegCommonStruct.AllocJpegSamples(total_colors, m_cinfo.outColorComponents); /* blksize is number of adjacent repeated entries for a component */ /* blkdist is distance between groups of identical entries for a component */ var blkdist = total_colors; for (var i = 0; i < m_cinfo.outColorComponents; i++) { /* fill in colormap entries for i'th color component */ var nci = m_Ncolors[i]; /* # of distinct values for this color */ var blksize = blkdist / nci; for (var j = 0; j < nci; j++) { /* Compute j'th output value (out of nci) for component */ var val = OutputValue(j, nci - 1); /* Fill in all colormap entries that have this value of this component */ for (var ptr = j * blksize; ptr < total_colors; ptr += blkdist) { /* fill in blksize entries beginning at ptr */ for (var k = 0; k < blksize; k++) { colormap[i][ptr + k] = (byte)val; } } } /* blksize of this color is blkdist of next */ blkdist = blksize; } /* Save the colormap in private storage, * where it will survive color quantization mode changes. */ m_sv_colormap = colormap; m_sv_actual = total_colors; }
public JpegCMainController(JpegCompressStruct cinfo) { m_cinfo = cinfo; /* Allocate a strip buffer for each component */ for (var ci = 0; ci < cinfo.m_num_components; ci++) { var compptr = cinfo.Component_info[ci]; m_buffer[ci] = JpegCommonStruct.AllocJpegSamples( compptr.Width_in_blocks * compptr.DCT_h_scaled_size, compptr.V_samp_factor * compptr.DCT_v_scaled_size); } }
public MyCCoefController(JpegCompressStruct cinfo, bool need_full_buffer) { m_cinfo = cinfo; /* Create the coefficient buffer. */ if (need_full_buffer) { /* Allocate a full-image virtual array for each component, */ /* padded to a multiple of samp_factor DCT blocks in each direction. */ for (var ci = 0; ci < cinfo.m_num_components; ci++) { m_whole_image[ci] = JpegCommonStruct.CreateBlocksArray( JpegUtils.jround_up(cinfo.Component_info[ci].Width_in_blocks, cinfo.Component_info[ci].H_samp_factor), JpegUtils.jround_up(cinfo.Component_info[ci].height_in_blocks, cinfo.Component_info[ci].V_samp_factor)); m_whole_image[ci].ErrorProcessor = cinfo; } } else { /* We only need a single-MCU buffer. */ var buffer = new JBlock[JpegConstants.C_MAX_BLOCKS_IN_MCU]; for (var i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++) { buffer[i] = new JBlock(); } for (var i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++) { m_MCU_buffer[i] = new JBlock[JpegConstants.C_MAX_BLOCKS_IN_MCU - i]; for (var j = i; j < JpegConstants.C_MAX_BLOCKS_IN_MCU; j++) { m_MCU_buffer[i][j - i] = buffer[j]; } } /* flag for no virtual arrays */ m_whole_image[0] = null; } }
/// <summary> /// Create the wrapped-around downsampling input buffer needed for context mode. /// </summary> private void CreateContextBuffer() { var rgroup_height = cinfo.m_max_v_samp_factor; for (var ci = 0; ci < cinfo.m_num_components; ci++) { var samplesPerRow = (cinfo.Component_info[ci].Width_in_blocks * cinfo.min_DCT_h_scaled_size * cinfo.m_max_h_samp_factor) / cinfo.Component_info[ci].H_samp_factor; var fake_buffer = new byte[5 * rgroup_height][]; for (var i = 1; i < 4 * rgroup_height; i++) { fake_buffer[i] = new byte[samplesPerRow]; } /* Allocate the actual buffer space (3 row groups) for this component. * We make the buffer wide enough to allow the downsampler to edge-expand * horizontally within the buffer, if it so chooses. */ var true_buffer = JpegCommonStruct.AllocJpegSamples(samplesPerRow, 3 * rgroup_height); /* Copy true buffer row pointers into the middle of the fake row array */ for (var i = 0; i < 3 * rgroup_height; i++) { fake_buffer[rgroup_height + i] = true_buffer[i]; } /* Fill in the above and below wraparound pointers */ for (var i = 0; i < rgroup_height; i++) { fake_buffer[i] = true_buffer[(2 * rgroup_height) + i]; fake_buffer[(4 * rgroup_height) + i] = true_buffer[i]; } colorBuf[ci] = fake_buffer; colorBufRowsOffset = rgroup_height; } }
public MyUpSampler(JpegDecompressStruct cinfo) { m_cinfo = cinfo; m_need_context_rows = false; /* until we find out differently */ if (cinfo.m_CCIR601_sampling) /* this isn't supported */ { cinfo.ErrExit(JMessageCode.JERR_CCIR601_NOTIMPL); } /* Verify we can handle the sampling factors, select per-component methods, * and create storage as needed. */ for (var ci = 0; ci < cinfo.numComponents; ci++) { var componentInfo = cinfo.CompInfo[ci]; /* Compute size of an "input group" after IDCT scaling. This many samples * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. */ var h_in_group = (componentInfo.H_samp_factor * componentInfo.DCT_h_scaled_size) / cinfo.min_DCT_h_scaled_size; var v_in_group = (componentInfo.V_samp_factor * componentInfo.DCT_v_scaled_size) / cinfo.min_DCT_v_scaled_size; var h_out_group = cinfo.m_max_h_samp_factor; var v_out_group = cinfo.m_maxVSampleFactor; /* save for use later */ m_rowgroup_height[ci] = v_in_group; if (!componentInfo.component_needed) { /* Don't bother to upsample an uninteresting component. */ m_upsampleMethods[ci] = ComponentUpsampler.noop_upsampler; continue; /* don't need to allocate buffer */ } if (h_in_group == h_out_group && v_in_group == v_out_group) { /* Fullsize components can be processed without any work. */ m_upsampleMethods[ci] = ComponentUpsampler.fullsize_upsampler; continue; /* don't need to allocate buffer */ } if (h_in_group * 2 == h_out_group && v_in_group == v_out_group) { /* Special case for 2h1v upsampling */ m_upsampleMethods[ci] = ComponentUpsampler.h2v1_upsampler; } else if (h_in_group * 2 == h_out_group && v_in_group * 2 == v_out_group) { /* Special case for 2h2v upsampling */ m_upsampleMethods[ci] = ComponentUpsampler.h2v2_upsampler; } else if ((h_out_group % h_in_group) == 0 && (v_out_group % v_in_group) == 0) { /* Generic integral-factors upsampling method */ m_upsampleMethods[ci] = ComponentUpsampler.int_upsampler; m_h_expand[ci] = (byte)(h_out_group / h_in_group); m_v_expand[ci] = (byte)(v_out_group / v_in_group); } else { cinfo.ErrExit(JMessageCode.JERR_FRACT_SAMPLE_NOTIMPL); } var cb = new ComponentBuffer(); cb.SetBuffer(JpegCommonStruct.AllocJpegSamples(JpegUtils.jround_up(cinfo.outputWidth, cinfo.m_max_h_samp_factor), cinfo.m_maxVSampleFactor), null, 0); m_color_buf[ci] = cb; } }
/// <summary> /// Create the color index table. /// </summary> private void CreateColorIndex() { /* For ordered dither, we pad the color index tables by MAXJSAMPLE in * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). * This is not necessary in the other dithering modes. However, we * flag whether it was done in case user changes dithering mode. */ int pad; if (m_cinfo.ditherMode == JDitherMode.JDITHER_ORDERED) { pad = JpegConstants.MAXJSAMPLE * 2; m_is_padded = true; } else { pad = 0; m_is_padded = false; } m_colorindex = JpegCommonStruct.AllocJpegSamples(JpegConstants.MAXJSAMPLE + 1 + pad, m_cinfo.outColorComponents); m_colorindexOffset = new int[m_cinfo.outColorComponents]; /* blksize is number of adjacent repeated entries for a component */ var blksize = m_sv_actual; for (var i = 0; i < m_cinfo.outColorComponents; i++) { /* fill in colorindex entries for i'th color component */ var nci = m_Ncolors[i]; /* # of distinct values for this color */ blksize /= nci; /* adjust colorindex pointers to provide padding at negative indexes. */ if (pad != 0) { m_colorindexOffset[i] += JpegConstants.MAXJSAMPLE; } /* in loop, val = index of current output value, */ /* and k = largest j that maps to current val */ var val = 0; var k = LargestInputValue(0, nci - 1); for (var j = 0; j <= JpegConstants.MAXJSAMPLE; j++) { while (j > k) { /* advance val if past boundary */ k = LargestInputValue(++val, nci - 1); } /* premultiply so that no multiplication needed in main processing */ m_colorindex[i][m_colorindexOffset[i] + j] = (byte)(val * blksize); } /* Pad at both ends if necessary */ if (pad != 0) { for (var j = 1; j <= JpegConstants.MAXJSAMPLE; j++) { m_colorindex[i][m_colorindexOffset[i] + -j] = m_colorindex[i][m_colorindexOffset[i]]; m_colorindex[i][m_colorindexOffset[i] + JpegConstants.MAXJSAMPLE + j] = m_colorindex[i][m_colorindexOffset[i] + JpegConstants.MAXJSAMPLE]; } } } }