#include "common.h" #include #include "defines.h" #include #include "common/image/jpeg12_utils.h" namespace hinode { ScienceHeader HinodeDepacketizer::parse_science_header(ccsds::CCSDSPacket &pkt) { ScienceHeader wk; uint8_t *p = &pkt.payload[0]; wk.DataType = p[12]; // DataType wk.PacketSize = p[13] << 16 | p[14] << 8 | p[15]; // PacketSize wk.SerialPacketNo = p[16] << 24 | p[17] << 16 | p[18] << 8 | p[19]; // SerialPacketNo wk.MainID = p[20] << 8 | p[21]; // MainID wk.MainSQFlag = (p[22] & 0xc0) >> 6; // MainSequenceFlag wk.MainSQCount = (p[22] & 0x3f) << 8 | p[23] << 0; // MainSequenceCount // p[30] ̏2 bit reserved wk.NumOfPacket = (p[24] & 0x3f) << 2 | (p[25] & 0xc0) >> 6; // NumberOfPacket wk.NumOfFrame = p[25] & 0x3f; // NumberOfFrame wk.SubID = p[26] << 8 | p[27]; // SubID wk.SubSQFlag = (p[28] & 0xc0) >> 6; // SequenceFlag wk.SubSQCount = (p[28] & 0x3f) << 8 | p[29]; // SequenceCount wk.FullImageSizeX = p[30] << 8 | p[31]; // FullImageSizeX wk.FullImageSizeY = p[32] << 8 | p[33]; // FullImageSizeY wk.BasePointCoorX = p[34] << 8 | p[35]; // BasePointCoorX wk.BasePointCoorY = p[36] << 8 | p[37]; // BasePointCoorY wk.PartImageSizeX = p[38] << 8 | p[39]; // PartImageSizeX wk.PartImageSizeY = p[40] << 8 | p[41]; // PartImageSizeY // p[48] 1 bit reserved wk.BitCompMode = (p[42] & 0x78) >> 3; // k[hibit) wk.ImageCompMode = p[42] & 0x07; // k[hiImage) // p[49] ̏1 bit reserved wk.HTACNo = (p[43] & 0x60) >> 5; // nt}ACNo wk.HTDCNo = (p[43] & 0x18) >> 3; // nt}DCNo wk.QTNo = p[43] & 0x07; // ʎqe[uNo { int restart_pixel = 99; // invalid int num_segment = 99; // invalid switch (wk.ImageCompMode) { case COMP_MODE_DPCM12: // DPCM���k for (restart_pixel = wk.PartImageSizeX; restart_pixel % 64 != 0;) { // ���X�^�[�g�Ԋu restart_pixel = restart_pixel * 2; } num_segment = (int)ceil(1.0 * wk.PartImageSizeX * wk.PartImageSizeY / restart_pixel); break; case COMP_MODE_DCT12: // DCT���k restart_pixel = 8 * 8 * 64; // ���X�^�[�g�Ԋu num_segment = (int)ceil(1.0 * wk.PartImageSizeX * wk.PartImageSizeY / restart_pixel); break; default: wk.ImageCompMode = 0; } wk.restart_pixel = restart_pixel; wk.num_segment = num_segment; } // uint32_t time = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; // double ttime = time + 946684800.0; // printf("TIME = %s\n", timestamp_to_string(ttime).c_str()); num_RST = 0; restored_flag = 0; buff_pos = 0; ECS0_start = 0; return wk; } HinodeDepacketizer::HinodeDepacketizer() { buffer = new uint8_t[MAX_COMP_LEN]; _chk_tbl = new uint8_t[MAX_PIXELS]; rst_tbl_array = new rst_tbl_t[MAX_RST]; status = JPEG_INIT; } HinodeDepacketizer::~HinodeDepacketizer() { delete[] buffer; delete[] _chk_tbl; delete[] rst_tbl_array; } int HinodeDepacketizer::work(ccsds::CCSDSPacket &pkt, DecodedImage *result) { // if (pkt.payload.size() == pkt.header.packet_length + 1) // return status; result->apid = -1; int wk = 0; int rst2ndNo = 0; if (status != BUFF_NOW) { /* 1. waiting for start of next image */ if (pkt.header.sequence_flag == 0b01) { sci_hdr = parse_science_header(pkt); if (sci_hdr.ImageCompMode != 0) { // JPEG data status = BUFF_NOW; before_sq_count = pkt.header.packet_sequence_count; before_sq_flag = pkt.header.sequence_flag; } else { // not JPEG data status = NOT_JPEG_DATA; } } if (status == JPEG_INIT) return JPEG_IRRETRIEVABLE; // KM note *12 return status; } else { /* 2. Processing of image */ rst_tbl_t *rst_tbl = &rst_tbl_array[0]; if (pkt.header.sequence_flag == 0b01) { /* 2.1. ���̓p�P�b�g����P�p�P�b�g�̏ꍇ */ /* finalize process of accumulated image */ int iret = 99; // invalid, determined soon if (before_sq_flag == 0b01) { /* 2.1.1. Processing of designed pattern 8 */ iret = JPEG_IRRETRIEVABLE; // discard accumlated image } else { /* 2.1.2. Processing of designed pattern 4, 10 */ fill_tail(); // recover RSTn, EOI [KM51] // Input: _sci_head.num_segment, Modified: num_RST, rst_tbl, buff_pos, buffer if (num_RST != sci_hdr.num_segment - 1) { // check number of RSTn /* recovery failed, retry recovery */ wk = trunc_recovered(); // [KM52], KM note *9) // Input: _sci_head.num_segment, Modified: num_RST, rst_tbl, buff_pos, buffer // dbg("KM52 wk=%d num_RST=%d num_segment=%d\n", wk, *num_RST, _sci_head->num_segment); if (wk != 0) { // dbg("KM72"); return status = JPEG_IRRETRIEVABLE; // discard accumlated image // KM: why return here ?? } } /* recovery succeeded */ clear_chktbl(); ////// fill_chktbl(); // Input: _sci_head, num_RST, rst_tbl, output: _chk_tbl { result->apid = pkt.header.apid; result->sci = sci_hdr; result->img = image::decompress_jpeg12(buffer, buff_pos); img_cnt++; } // dbg("KM61"); iret = JPEG_RESTORED; /* end of 2.1.2. */ } sci_hdr = parse_science_header(pkt); if (sci_hdr.ImageCompMode != 0) { // JPEG data status = BUFF_NOW; before_sq_count = pkt.header.packet_sequence_count; before_sq_flag = pkt.header.sequence_flag; } else { // not JPEG data status = NOT_JPEG_DATA; } return iret; /* end of 2.1. */ } else { /* 2.2. ���̓p�P�b�g����P�p�P�b�g�ȊO�̏ꍇ */ int istatus = BUFF_NOW; int istart_flag = 1; const int data_length = pkt.header.packet_length + 1 - 4; const int sq_count_diff = (pkt.header.packet_sequence_count - before_sq_count + ALIGN) % ALIGN; if (sq_count_diff >= MAX_SQDIFF) { /* 2.2.1. too large counter skip */ if (before_sq_flag == 0b01) { // dbg("KM73"); return status = JPEG_IRRETRIEVABLE; // discard accumulated image } else { fill_tail(); // recover RSTn, EOI [KM54] KM note *10) // Input: _sci_head.num_segment, Modified: num_RST, rst_tbl, buff_pos, buffer // dbg("KM73a"); istatus = RESTORED_IRRETRIEVABLE; // finish accumulation of image istart_flag = 0; } /* end of 2.2.1. */ } else if (sq_count_diff > 1) { /* 2.2.2. not too large counter skip */ /* ���͂����p�P�b�g����RSTn�̌��� */ int packetpos = -1; #if 0 for (i=0; i= 0) { const int rst2nd = octet & RST2ND_MASK; rst2ndNo = octet & RSTNO_MASK; if (rst2nd == 0xD0) { // RSTn�����‚����� rst_tbl[num_RST].pos = markpos; rst_tbl[num_RST].No = rst2ndNo; rst_tbl[num_RST].flg = 0; num_RST++; } else if (octet == 0xDA) { // SOS �����‚����� ECS0_start = buff_pos + 9; // �摜�f�[�^�̊J�n�ʒu�́ASOS �}�[�J�̂Q�o�C�g�ڂ���A�X�o�C�g��ɂ���B // KM notice *3 from here } else if (octet == 0xD9) { // EOI rst_tbl[num_RST].flg = 0; // KM notice *3 until here } } markpos = -1; } buff_pos++; } if (pkt.header.sequence_flag == 0b10) { //// dbg("KM64"); istatus = JPEG_RESTORED; // finsish accumulation of image istart_flag = 0; } else { // istatus = BUFF_NOW; // continue accumlation of image } /* end of 2.2.3. */ } if (istatus != BUFF_NOW) { clear_chktbl(); // Output: _chk_tbl } if (istatus == JPEG_RESTORED && istart_flag == 0) { if (restored_flag == 0) { istatus = JPEG_EXTRACT; } else { if (num_RST != sci_hdr.num_segment - 1) { // check number of RSTn /* recovery failed, retry recovery */ wk = trunc_recovered(); // [KM57] // Input: _sci_head.num_segment, Modified: num_RST, rst_tbl, buff_pos, buffer if (wk != 0) { // dbg("KM75"); return status = JPEG_IRRETRIEVABLE; // discard accumlated image } // dbg("KM75a"); istatus = RESTORED_IRRETRIEVABLE; // finish accumulation of image } /* recovery succeeded */ clear_chktbl(); ////// fill_chktbl(); // Input: _sci_head, num_RST, rst_tbl, output: _chk_tbl } } if (istatus != BUFF_NOW) { /* JPEG_EXTRACT or JPEG_RESTORED or RESTORED_IRRETRIEVABLE */ /* JPEG �f�[�^���i�[�����o�b�t�@�̃|�C���^��Ԃ� */ { result->apid = pkt.header.apid; result->sci = sci_hdr; result->img = image::decompress_jpeg12(buffer, buff_pos); img_cnt++; } } else { /* BUFF_NOW */ /* NULL ��Ԃ� */ before_sq_count = pkt.header.packet_sequence_count; before_sq_flag = pkt.header.sequence_flag; } switch (istatus) { case JPEG_EXTRACT: case JPEG_RESTORED: status = (istart_flag == 0) ? NOT_JPEG_DATA : BUFF_NOW; break; case RESTORED_IRRETRIEVABLE: status = (istart_flag == 0) ? JPEG_IRRETRIEVABLE : BUFF_NOW; break; case BUFF_NOW: status = BUFF_NOW; break; default: fprintf(stderr, "DePacketizeBody(): fatal logic error (1266)\n"); } return istatus; /* end of 2.2. */ } /* end of 2. */ } } }