Esempio n. 1
0
        // Create the wrapped-around downsampling input buffer needed for context mode.
        static void create_context_buffer(jpeg_compress cinfo)
        {
            my_prep_controller prep = (my_prep_controller)cinfo.prep;
            int rgroup_height       = cinfo.max_v_samp_factor;

            for (int ci = 0; ci < cinfo.num_components; ci++)
            {
                jpeg_component_info compptr = cinfo.comp_info[ci];

                // Grab enough space for fake row pointers;
                // we need five row groups' worth of pointers for each component.
                byte[][] fake_buffer = new byte[5 * rgroup_height][];

                // 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.
                byte[][] true_buffer = alloc_sarray(cinfo,
                                                    (uint)(((int)compptr.width_in_blocks * cinfo.DCT_size * cinfo.max_h_samp_factor) / compptr.h_samp_factor),
                                                    (uint)(3 * rgroup_height));

                // Copy true buffer row pointers into the middle of the fake row array
                Array.Copy(true_buffer, 0, fake_buffer, rgroup_height, 3 * rgroup_height);

                // Fill in the above and below wraparound pointers
                for (int i = 0; i < rgroup_height; i++)
                {
                    fake_buffer[i] = true_buffer[2 * rgroup_height + i];
                    fake_buffer[4 * rgroup_height + i] = true_buffer[i];
                }
                prep.color_buf[ci] = fake_buffer;
            }
        }
Esempio n. 2
0
        // Initialize preprocessing controller.
        static void jinit_c_prep_controller(jpeg_compress cinfo, bool need_full_buffer)
        {
            if (need_full_buffer)
            {
                ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_BUFFER_MODE);                              // safety check
            }
            my_prep_controller prep = null;

            try
            {
                prep = new my_prep_controller();
            }
            catch
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
            }
            cinfo.prep      = prep;
            prep.start_pass = start_pass_prep;

            // Allocate the color conversion buffer.
            // We make the buffer wide enough to allow the downsampler to edge-expand
            // horizontally within the buffer, if it so chooses.
            if (cinfo.downsample.need_context_rows)
            {
                // Set up to provide context rows
#if CONTEXT_ROWS_SUPPORTED
                prep.pre_process_data = pre_process_context;
                create_context_buffer(cinfo);
#else
                ERREXIT(cinfo, J_MESSAGE_CODE.JERR_NOT_COMPILED);
#endif
            }
            else
            {
                // No context, just make it tall enough for one row group
                prep.pre_process_data = pre_process_data;
                for (int ci = 0; ci < cinfo.num_components; ci++)
                {
                    jpeg_component_info compptr = cinfo.comp_info[ci];
                    prep.color_buf[ci] = alloc_sarray(cinfo,
                                                      (uint)(((int)compptr.width_in_blocks * cinfo.DCT_size * cinfo.max_h_samp_factor) / compptr.h_samp_factor),
                                                      (uint)cinfo.max_v_samp_factor);
                }
            }
        }
Esempio n. 3
0
        // Process some data in the simple no-context case.
        //
        // Preprocessor output data is counted in "row groups". A row group
        // is defined to be v_samp_factor sample rows of each component.
        // Downsampling will produce this much data from each max_v_samp_factor input rows.
        static void pre_process_data(jpeg_compress cinfo, byte[][] input_buf, ref uint in_row_ctr, uint in_rows_avail, byte[][][] output_buf, ref uint out_row_group_ctr, uint out_row_groups_avail)
        {
            my_prep_controller prep = (my_prep_controller)cinfo.prep;

            while (in_row_ctr < in_rows_avail && out_row_group_ctr < out_row_groups_avail)
            {
                // Do color conversion to fill the conversion buffer.
                uint inrows  = in_rows_avail - in_row_ctr;
                int  numrows = cinfo.max_v_samp_factor - prep.next_buf_row;
                numrows = (int)Math.Min((uint)numrows, inrows);
                cinfo.cconvert.color_convert(cinfo, input_buf, in_row_ctr, prep.color_buf, (uint)prep.next_buf_row, numrows);
                in_row_ctr        += (uint)numrows;
                prep.next_buf_row += numrows;
                prep.rows_to_go   -= (uint)numrows;
                // If at bottom of image, pad to fill the conversion buffer.
                if (prep.rows_to_go == 0 && prep.next_buf_row < cinfo.max_v_samp_factor)
                {
                    for (int ci = 0; ci < cinfo.num_components; ci++)
                    {
                        expand_bottom_edge(prep.color_buf[ci], cinfo.image_width, prep.next_buf_row, cinfo.max_v_samp_factor);
                    }
                    prep.next_buf_row = cinfo.max_v_samp_factor;
                }
                // If we've filled the conversion buffer, empty it.
                if (prep.next_buf_row == cinfo.max_v_samp_factor)
                {
                    cinfo.downsample.downsample(cinfo, prep.color_buf, 0, output_buf, out_row_group_ctr);
                    prep.next_buf_row = 0;
                    out_row_group_ctr++;
                }
                // If at bottom of image, pad the output to a full iMCU height.
                // Note we assume the caller is providing a one-iMCU-height output buffer!
                if (prep.rows_to_go == 0 && out_row_group_ctr < out_row_groups_avail)
                {
                    for (int ci = 0; ci < cinfo.num_components; ci++)
                    {
                        jpeg_component_info compptr = cinfo.comp_info[ci];
                        expand_bottom_edge(output_buf[ci], compptr.width_in_blocks * cinfo.DCT_size, (int)(out_row_group_ctr * compptr.v_samp_factor), (int)(out_row_groups_avail * compptr.v_samp_factor));
                    }
                    out_row_group_ctr = out_row_groups_avail;
                    break; // can exit outer loop without test
                }
            }              // while(...)
        }
Esempio n. 4
0
        // Initialize for a processing pass.
        static void start_pass_prep(jpeg_compress cinfo, J_BUF_MODE pass_mode)
        {
            my_prep_controller prep = (my_prep_controller)cinfo.prep;

            if (pass_mode != J_BUF_MODE.JBUF_PASS_THRU)
            {
                ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_BUFFER_MODE);
            }

            // Initialize total-height counter for detecting bottom of image
            prep.rows_to_go = cinfo.image_height;
            // Mark the conversion buffer empty
            prep.next_buf_row = 0;
#if CONTEXT_ROWS_SUPPORTED
            // Preset additional state variables for context mode.
            // These aren't used in non-context mode, so we needn't test which mode.
            prep.this_row_group = 0;
            // Set next_buf_stop to stop after two row groups have been read in.
            prep.next_buf_stop = 2 * cinfo.max_v_samp_factor;
#endif
        }
Esempio n. 5
0
		// Initialize preprocessing controller.
		static void jinit_c_prep_controller(jpeg_compress cinfo, bool need_full_buffer)
		{
			if(need_full_buffer) ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_BUFFER_MODE); // safety check

			my_prep_controller prep=null;

			try
			{
				prep=new my_prep_controller();
			}
			catch
			{
				ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
			}
			cinfo.prep=prep;
			prep.start_pass=start_pass_prep;

			// Allocate the color conversion buffer.
			// We make the buffer wide enough to allow the downsampler to edge-expand
			// horizontally within the buffer, if it so chooses.
			if(cinfo.downsample.need_context_rows)
			{
				// Set up to provide context rows
#if CONTEXT_ROWS_SUPPORTED
				prep.pre_process_data=pre_process_context;
				create_context_buffer(cinfo);
#else
				ERREXIT(cinfo, J_MESSAGE_CODE.JERR_NOT_COMPILED);
#endif
			}
			else
			{
				// No context, just make it tall enough for one row group
				prep.pre_process_data=pre_process_data;
				for(int ci=0; ci<cinfo.num_components; ci++)
				{
					jpeg_component_info compptr=cinfo.comp_info[ci];
					prep.color_buf[ci]=alloc_sarray(cinfo,
						(uint)(((int)compptr.width_in_blocks*cinfo.DCT_size*cinfo.max_h_samp_factor)/compptr.h_samp_factor),
						(uint)cinfo.max_v_samp_factor);
				}
			}
		}
Esempio n. 6
0
        // Process some data in the context case.
        static void pre_process_context(jpeg_compress cinfo, byte[][] input_buf, ref uint in_row_ctr, uint in_rows_avail, byte[][][] output_buf, ref uint out_row_group_ctr, uint out_row_groups_avail)
        {
            my_prep_controller prep = (my_prep_controller)cinfo.prep;
            int buf_height          = cinfo.max_v_samp_factor * 3;
            int rgroup_height       = cinfo.max_v_samp_factor;

            while (out_row_group_ctr < out_row_groups_avail)
            {
                if (in_row_ctr < in_rows_avail)
                {
                    // Do color conversion to fill the conversion buffer.
                    uint inrows  = in_rows_avail - in_row_ctr;
                    int  numrows = prep.next_buf_stop - prep.next_buf_row;
                    numrows = (int)Math.Min((uint)numrows, inrows);
                    cinfo.cconvert.color_convert(cinfo, input_buf, in_row_ctr, prep.color_buf, (uint)rgroup_height + (uint)prep.next_buf_row, numrows);

                    // Pad at top of image, if first time through
                    if (prep.rows_to_go == cinfo.image_height)
                    {
                        for (int ci = 0; ci < cinfo.num_components; ci++)
                        {
                            for (int row = 1; row <= cinfo.max_v_samp_factor; row++)
                            {
                                jcopy_sample_rows(prep.color_buf[ci], rgroup_height, prep.color_buf[ci], rgroup_height - row, 1, cinfo.image_width);
                            }
                        }
                    }
                    in_row_ctr        += (uint)numrows;
                    prep.next_buf_row += numrows;
                    prep.rows_to_go   -= (uint)numrows;
                }
                else
                {
                    // Return for more data, unless we are at the bottom of the image.
                    if (prep.rows_to_go != 0)
                    {
                        break;
                    }

                    // When at bottom of image, pad to fill the conversion buffer.
                    if (prep.next_buf_row < prep.next_buf_stop)
                    {
                        for (int ci = 0; ci < cinfo.num_components; ci++)
                        {
                            expand_bottom_edge(prep.color_buf[ci], cinfo.image_width, rgroup_height + prep.next_buf_row, rgroup_height + prep.next_buf_stop);
                        }

                        prep.next_buf_row = prep.next_buf_stop;
                    }
                }

                // If we've gotten enough data, downsample a row group.
                if (prep.next_buf_row == prep.next_buf_stop)
                {
                    cinfo.downsample.downsample(cinfo, prep.color_buf, (uint)rgroup_height + (uint)prep.this_row_group, output_buf, out_row_group_ctr);
                    out_row_group_ctr++;

                    // Advance pointers with wraparound as necessary.
                    prep.this_row_group += cinfo.max_v_samp_factor;
                    if (prep.this_row_group >= buf_height)
                    {
                        prep.this_row_group = 0;
                    }
                    if (prep.next_buf_row >= buf_height)
                    {
                        prep.next_buf_row = 0;
                    }
                    prep.next_buf_stop = prep.next_buf_row + cinfo.max_v_samp_factor;
                }
            }             // while(...)
        }