#ifndef JDECODER_HPP_ #define JDECODER_HPP_ #include "idct.h" #include "bstream.hpp" namespace JPEG { // マーカからそれぞれ文字列を得る const char *getMarkerDescription(unsigned int m); /////////////////////////////////////////////////////////////////////////////// struct HuffmanTree{ enum { ERROR_VALUE = 9999 }; HuffmanTree *next_tree[2]; int value[2]; HuffmanTree() { next_tree[0] = 0; next_tree[1] = 0; value[0] = ERROR_VALUE; value[1] = ERROR_VALUE; } ~HuffmanTree() { delete next_tree[0]; delete next_tree[1]; } }; /////////////////////////////////////////////////////////////////////////////// class Decoder { enum { JUST_A_0xFF = 0xFF00, START_OF_FRAME_MIN = 0xFFC0, START_OF_FRAME_0 = 0xFFC0, START_OF_FRAME_2 = 0xFFC2, START_OF_FRAME_MAX = 0xFFC3, DEFINE_HUFFMAN_TABLE =0xFFC4, START_OF_IMAGE = 0xFFD8, END_OF_IMAGE = 0xFFD9, START_OF_SCAN = 0xFFDA, DEFINE_QUANTIZATION_TABLE = 0xFFDB, DEFINE_RESTART_INTERVAL = 0xFFDD, APPLICATION_MIN = 0xFFE0, APPLICATION_0 = 0xFFE0, APPLICATION_MAX = 0xFFEF, }; // APP0 char app0_identifier_[5]; // "JFIF\0" 固定のはず // app0_identifier == "JFIF\0" の場合 int major_revision_; int minor_revision_; int density_unit_; int horiz_density_; int verti_density_; int thumb_width_; int thumb_height_; // サムネイル画像は略 int SOF_number_; // SOF int depth_per_component_; int height_; int width_; int component_count_; // 1 or 3 int component_id_[3]; int sampling_factor_[3]; int horizontal_sampling_factor_[3]; int vertical_sampling_factor_[3]; int qt_selector_[3]; // SOF 取得後,便宜的に計算しておくとよいもの int depth_; int bytes_per_pixel_; int bytes_per_line_; int max_horizontal_sampling_factor_; //! サンプリングファクタのの横方向の最大値 int max_vertical_sampling_factor_; //! サンプリングファクタのの縦方向の最大値 int decoding_unit_height_; unsigned char *decoded_image_; int coeff_workspace_width_[3]; int coeff_workspace_height_[3]; short *coeff_workspace_[3]; short *progcoeff_workspace_[3]; // DQT short quant_tables_[3][64]; // DHT HuffmanTree huffman_trees_[2][4]; //DRI m_ui32 expected_rst_; // 次に出現するはずのリスタートインターバル m_ui32 restart_interval_; m_ui32 restart_count_; // SOS int component_count_in_scan_; int components_in_scan_[3]; int huffman_tree_for_dc_[3]; int huffman_tree_for_ac_[3]; int Ss_, Se_, Ah_, Al_; // prepare_others_at_SOS() int MCU_width_on_image_; int MCU_height_on_image_; int max_vertical_sampling_factor_in_scan_; int horizontal_MCU_count_in_scan_; int horizontal_8x8_block_count_in_MCU_[3]; int vertical_8x8_block_count_in_MCU_[3]; // その他 BitwiseInputStreamReader stream_; bool process_scan_; bool image_end_; int getting_line_; //int horiz_pos_, verti_pos_; int dc_pred_[3]; bool skip_next_0x00_; int decoded_count_; int end_of_band_run_; unsigned long get_marker(); void process_segments(); void segment_startOfImage(); void segment_application0(); void segment_defineQuantizationTable(); void segment_startOfFrame_sub(); void segment_startOfFrame0(); void segment_startOfFrame2(); void segment_defineHuffmanTable(); void segment_defineRestartInterval(); void segment_startOfScan(); void segment_unknown(); void segment_restartMarker(); int find_component_index( int ); void process_restart_marker(); void decode_a_line(); void decode_a_MCU( short *[3] ); void dispatch_method_decodes_8x8_block( int, short * ); void decode_8x8_block( int, short * ); void decode_DC_refine( int, short * ); void decode_AC_refine( int, short * ); m_ui32 decode_huffman_tree( HuffmanTree *); m_ui32 read_bits_scan( unsigned int bits ); short read_coeff( int ); void dequantize( int, short * ); void construct_image( short *[3] ); //void decode_MCU_line(); //void block_to_image(int); //void decode_block(short *, int ); public: Decoder( InputStream *stream ); virtual ~Decoder(){ delete decoded_image_; for (int c=0; c