// Check for a restart marker & resynchronize decoder, undifferencer. // Returns false if must suspend. static bool process_restart_d_diff(jpeg_decompress cinfo) { jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef; d_diff_controller diff = (d_diff_controller)losslsd.diff_private; if (!losslsd.entropy_process_restart(cinfo)) { return(false); } losslsd.predict_process_restart(cinfo); // Reset restart counter diff.restart_rows_to_go = cinfo.restart_interval / cinfo.MCUs_per_row; return(true); }
// Decode and return nMCU's worth of Huffman-compressed differences. // Each MCU is also disassembled and placed accordingly in diff_buf. // // MCU_col_num specifies the column of the first MCU being requested within // the MCU-row. This tells us where to position the output row pointers in // diff_buf. // // Returns the number of MCUs decoded. This may be less than nMCU if data // source requested suspension. In that case no changes have been made to // permanent state. (Exception: some output differences may already have // been assigned. This is harmless for this module, since we'll just // re-assign them on the next call.) static uint decode_mcus_dlhuff(jpeg_decompress cinfo, int[][][] diff_buf, uint MCU_row_num, uint MCU_col_num, uint nMCU) { jpeg_lossless_d_codec losslsd = (jpeg_lossless_d_codec)cinfo.coef; lhuff_entropy_decoder entropy = (lhuff_entropy_decoder)losslsd.entropy_private; // Set output pointer locations based on MCU_col_num for (int ptrn = 0; ptrn < entropy.num_output_ptrs; ptrn++) { int ci = entropy.output_ptr_info[ptrn].ci; int yoffset = entropy.output_ptr_info[ptrn].yoffset; int MCU_width = entropy.output_ptr_info[ptrn].MCU_width; entropy.output_ptr[ptrn] = diff_buf[ci][MCU_row_num + yoffset]; entropy.output_ptr_ind[ptrn] = (int)(MCU_col_num * MCU_width); } // If we've run out of data, zero out the buffers and return. // By resetting the undifferencer, the output samples will be CENTERJSAMPLE. // // NB: We should find a way to do this without interacting with the // undifferencer module directly. if (entropy.insufficient_data) { for (int ptrn = 0; ptrn < entropy.num_output_ptrs; ptrn++) { for (int i = 0; i < nMCU * entropy.output_ptr_info[ptrn].MCU_width; i++) { entropy.output_ptr[ptrn][entropy.output_ptr_ind[ptrn] + i] = 0; } } losslsd.predict_process_restart(cinfo); } else { // Load up working state //was BITREAD_STATE_VARS; bitread_working_state br_state = new bitread_working_state(); //was BITREAD_LOAD_STATE(cinfo, entropy.bitstate); br_state.cinfo = cinfo; br_state.input_bytes = cinfo.src.input_bytes; br_state.next_input_byte = cinfo.src.next_input_byte; br_state.bytes_in_buffer = cinfo.src.bytes_in_buffer; ulong get_buffer = entropy.bitstate.get_buffer; int bits_left = entropy.bitstate.bits_left; // Outer loop handles the number of MCU requested for (uint mcu_num = 0; mcu_num < nMCU; mcu_num++) { // Inner loop handles the samples in the MCU for (int sampn = 0; sampn < cinfo.blocks_in_MCU; sampn++) { d_derived_tbl dctbl = entropy.cur_tbls[sampn]; int s = 0, r; // Section H.2.2: decode the sample difference //was HUFF_DECODE(s, br_state, dctbl, return mcu_num, label1); { int nb, look; bool label = false; if (bits_left < HUFF_LOOKAHEAD) { if (!jpeg_fill_bit_buffer(ref br_state, get_buffer, bits_left, 0)) { return(mcu_num); } get_buffer = br_state.get_buffer; bits_left = br_state.bits_left; if (bits_left < HUFF_LOOKAHEAD) { nb = 1; label = true; if ((s = jpeg_huff_decode(ref br_state, get_buffer, bits_left, dctbl, nb)) < 0) { return(mcu_num); } get_buffer = br_state.get_buffer; bits_left = br_state.bits_left; } } if (!label) { //was look=PEEK_BITS(HUFF_LOOKAHEAD); look = ((int)(get_buffer >> (bits_left - HUFF_LOOKAHEAD))) & ((1 << HUFF_LOOKAHEAD) - 1); if ((nb = dctbl.look_nbits[look]) != 0) { //was DROP_BITS(nb); bits_left -= nb; s = dctbl.look_sym[look]; } else { nb = HUFF_LOOKAHEAD + 1; if ((s = jpeg_huff_decode(ref br_state, get_buffer, bits_left, dctbl, nb)) < 0) { return(mcu_num); } get_buffer = br_state.get_buffer; bits_left = br_state.bits_left; } } } if (s != 0) { if (s == 16) { s = 32768; // special case: always output 32768 } else { // normal case: fetch subsequent bits //was CHECK_BIT_BUFFER(br_state, s, return mcu_num); if (bits_left < s) { if (!jpeg_fill_bit_buffer(ref br_state, get_buffer, bits_left, s)) { return(mcu_num); } get_buffer = br_state.get_buffer; bits_left = br_state.bits_left; } //was r = GET_BITS(s); r = ((int)(get_buffer >> (bits_left -= s))) & ((1 << s) - 1); //was s=HUFF_EXTEND(r, s); s = (r < (1 << (s - 1))?r + (((-1) << s) + 1):r); } } // Output the sample difference int ind = entropy.output_ptr_index[sampn]; entropy.output_ptr[ind][entropy.output_ptr_ind[ind]++] = (int)s; } // Completed MCU, so update state //was BITREAD_SAVE_STATE(cinfo, entropy.bitstate); cinfo.src.input_bytes = br_state.input_bytes; cinfo.src.next_input_byte = br_state.next_input_byte; cinfo.src.bytes_in_buffer = br_state.bytes_in_buffer; entropy.bitstate.get_buffer = get_buffer; entropy.bitstate.bits_left = bits_left; } } return(nMCU); }