/// <summary> /// Read one row of pixels. /// The image has been read into the whole_image array, but is otherwise /// unprocessed. We must read it out in top-to-bottom row order, and if /// it is an 8-bit image, we must expand colormapped pixels to 24bit format. /// This version is for reading 8-bit colormap indexes. /// </summary> private int get_8bit_row() { /* Fetch next row from virtual array */ source_row--; byte[][] image_ptr = whole_image.Access(source_row, 1); /* Expand the colormap indexes to real data */ int imageIndex = 0; int outIndex = 0; for (int col = cinfo.Image_width; col > 0; col--) { int t = image_ptr[0][imageIndex]; imageIndex++; buffer[0][outIndex] = colormap[0][t]; /* can omit GETbyte() safely */ outIndex++; buffer[0][outIndex] = colormap[1][t]; outIndex++; buffer[0][outIndex] = colormap[2][t]; outIndex++; } return(1); }
/// <summary> /// Initialize for a processing pass. /// </summary> public void start_pass(J_BUF_MODE pass_mode) { switch (pass_mode) { case J_BUF_MODE.JBUF_PASS_THRU: if (m_cinfo.m_quantize_colors) { /* Single-pass processing with color quantization. */ m_processor = ProcessorType.OnePass; /* We could be doing buffered-image output before starting a 2-pass * color quantization; in that case, jinit_d_post_controller did not * allocate a strip buffer. Use the virtual-array buffer as workspace. */ if (m_buffer == null) { m_buffer = m_whole_image.Access(0, m_strip_height); } } else { /* For single-pass processing without color quantization, * I have no work to do; just call the upsampler directly. */ m_processor = ProcessorType.Upsample; } break; case J_BUF_MODE.JBUF_SAVE_AND_PASS: /* First pass of 2-pass quantization */ if (m_whole_image == null) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_BUFFER_MODE); } m_processor = ProcessorType.PrePass; break; case J_BUF_MODE.JBUF_CRANK_DEST: /* Second pass of 2-pass quantization */ if (m_whole_image == null) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_BUFFER_MODE); } m_processor = ProcessorType.SecondPass; break; default: m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_BUFFER_MODE); break; } m_starting_row = m_next_row = 0; }
/// <summary> /// Finish up at the end of the file. /// Here is where we really output the BMP file. /// </summary> public override void finish_output() { /* Write the header and colormap */ if (is_os2) { write_os2_header(); } else { write_bmp_header(); } cdjpeg_progress_mgr progress = cinfo.Progress as cdjpeg_progress_mgr; /* Write the file body from our virtual array */ for (int row = cinfo.Output_height; row > 0; row--) { if (progress != null) { progress.Pass_counter = cinfo.Output_height - row; progress.Pass_limit = cinfo.Output_height; progress.Updated(); } byte[][] image_ptr = whole_image.Access(row - 1, 1); int imageIndex = 0; for (int col = row_width; col > 0; col--) { output_file.WriteByte(image_ptr[0][imageIndex]); imageIndex++; } } if (progress != null) { progress.completed_extra_passes++; } /* Make sure we wrote the output file OK */ output_file.Flush(); }