00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly.h>
00021 #include <mxcpcMxPEGDecoderBackEnd.h>
00022 #include <mxcpcJPEGReceiver.h>
00023 #include <mxcpc_exceptions.h>
00024
00025 #include <memory>
00026
00027
00028
00029 const int mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::ZigZagMap[64] = {
00030 0, 1, 8, 16, 9, 2, 3, 10,
00031 17, 24, 32, 25, 18, 11, 4, 5,
00032 12, 19, 26, 33, 40, 48, 41, 34,
00033 27, 20, 13, 6, 7, 14, 21, 28,
00034 35, 42, 49, 56, 57, 50, 43, 36,
00035 29, 22, 15, 23, 30, 37, 44, 51,
00036 58, 59, 52, 45, 38, 31, 39, 46,
00037 53, 60, 61, 54, 47, 55, 62, 63
00038 };
00039
00040 const unsigned char mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00041 ::ZigZag_StoreMap[64] = {
00042 0, 1, 5, 6, 14, 15, 27, 28,
00043 2, 4, 7, 13, 16, 26, 29, 42,
00044 3, 8, 12, 17, 25, 30, 41, 43,
00045 9, 11, 18, 24, 31, 40, 44, 53,
00046 10, 19, 23, 32, 39, 45, 52, 54,
00047 20, 22, 33, 38, 46, 51, 55, 60,
00048 21, 34, 37, 47, 50, 56, 59, 61,
00049 35, 36, 48, 49, 57, 58, 62, 63
00050 };
00051
00052 const mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::HuffCompDC
00053 mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::HuffTbl_Y_UV_DC[2] ={
00054 {
00055 { 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
00056
00057 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
00058
00059 },
00060 {
00061 { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
00062
00063 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
00064
00065 }
00066 };
00067
00068 const mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::HuffCompAC
00069 mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::HuffTbl_Y_UV_AC[2] ={
00070 {
00071 { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d },
00072 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
00073 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
00074 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
00075 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
00076 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
00077 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
00078 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
00079 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
00080 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
00081 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
00082 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
00083 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
00084 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
00085 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
00086 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
00087 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
00088 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
00089 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
00090 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
00091 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
00092 0xf9, 0xfa
00093 },
00094 },
00095 {
00096 { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 },
00097 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
00098 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
00099 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
00100 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
00101 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
00102 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
00103 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
00104 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
00105 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
00106 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
00107 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
00108 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
00109 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
00110 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
00111 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
00112 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
00113 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
00114 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
00115 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
00116 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
00117 0xf9, 0xfa
00118 },
00119 }
00120 };
00121
00122 mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::FoldedHuffTbl_DC_AC
00123 mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::Huff_Y_UV[2];
00124
00125 mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::HuffmanBufferStateStructure
00126 mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::HuffmanBufferState;
00127
00128
00129 mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00130 ::mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly(
00131 mxcpcJPEGReceiver *receiver
00132 ) : mxcpcFramewiseMxPEGScanToJPEGConverter(receiver) {
00133
00134 char txt[100];
00135
00136
00137 HuffmanEncoderBuffer
00138 = new mxcpc::u8[MXCPC_FRAMEWISEMXPEGSCANTOJPEGCONVERTER_BITSTREAM_BUFFSIZE];
00139 initHuffmanEncoderBufferState();
00140
00141
00142 calcFoldedHuffTables();
00143
00144
00145
00146 HuffmanTree_Y_DC = 0,
00147 HuffmanTree_Y_AC = 0;
00148 HuffmanTree_UV_DC = 0,
00149 HuffmanTree_UV_AC = 0;
00150
00151 try {
00152
00153 HuffmanTree_Y_DC = new mxcpcHuffmanTree();
00154 if(HuffmanTree_Y_DC->configureFromTable(DefaultHuffmanTable_Y_DC))
00155 throw mxcpcDidntWorkOutException();
00156 HuffmanTree_Y_AC = new mxcpcHuffmanTree();
00157 if(HuffmanTree_Y_AC->configureFromTable(DefaultHuffmanTable_Y_AC))
00158 throw mxcpcDidntWorkOutException();
00159 HuffmanTree_UV_DC = new mxcpcHuffmanTree();
00160 if(HuffmanTree_UV_DC->configureFromTable(DefaultHuffmanTable_UV_DC))
00161 throw mxcpcDidntWorkOutException();
00162 HuffmanTree_UV_AC = new mxcpcHuffmanTree();
00163 if(HuffmanTree_UV_AC->configureFromTable(DefaultHuffmanTable_UV_AC))
00164 throw mxcpcDidntWorkOutException();
00165
00166 } catch(std::exception &e) {
00167
00168 MXCPC_RETHROW_UNHANDLED_EXCEPTION(e);
00169
00170 delete HuffmanTree_Y_DC;
00171 delete HuffmanTree_Y_AC;
00172 delete HuffmanTree_UV_DC;
00173 delete HuffmanTree_UV_AC;
00174
00175 throw;
00176 }
00177
00178
00179 int i;
00180 for(i = 0; i < 64; i++) {
00181 QuantizationTable_Y[i] = 0;
00182 QuantizationTable_UV[i] = 0;
00183 }
00184
00185 std::sprintf(txt, "symbols in Y/DC Huffman table : %d",
00186 HuffmanTree_Y_DC->countLeaves());
00187 mxcpc::sendStatusMsg(txt, this);
00188 std::sprintf(txt, "symbols in Y/AC Huffman table : %d",
00189 HuffmanTree_Y_AC->countLeaves());
00190 mxcpc::sendStatusMsg(txt, this);
00191 std::sprintf(txt, "symbols in UV/DC Huffman table : %d",
00192 HuffmanTree_UV_DC->countLeaves());
00193 mxcpc::sendStatusMsg(txt, this);
00194 std::sprintf(txt, "symbols in UV/AC Huffman table : %d",
00195 HuffmanTree_UV_AC->countLeaves());
00196 mxcpc::sendStatusMsg(txt, this);
00197
00198
00199 CoeffBuffer = 0;
00200 TileNumX = TileNumY = 0;
00201
00202 FramesProcessed = 0;
00203
00204
00205 APP0_Block.ff = 0xff;
00206 APP0_Block.app0_marker = mxcpc_mxpeg::MarkerId_APP0;
00207 APP0_Block.len_hi = (sizeof(mxcpc_mxpeg::APP0) - 2) / 256;
00208 APP0_Block.len_lo = (sizeof(mxcpc_mxpeg::APP0) - 2) % 256;
00209 std::strcpy(APP0_Block.id, "JFIF");
00210 APP0_Block.major_vers = 0x01;
00211 APP0_Block.minor_vers = 0x01;
00212 APP0_Block.units = 0x00;
00213 APP0_Block.xdpu_hi = 0;
00214 APP0_Block.xdpu_lo = 1;
00215 APP0_Block.ydpu_hi = 0;
00216 APP0_Block.ydpu_lo = 1;
00217 APP0_Block.thumbnail_x = 0;
00218 APP0_Block.thumbnail_y = 0;
00219
00220
00221 SOF0_Block.ff = 0xff;
00222 SOF0_Block.marker = mxcpc_mxpeg::MarkerId_SOF0;
00223 SOF0_Block.len_hi = (sizeof(mxcpc_mxpeg::SOF0) - 2) / 256;
00224 SOF0_Block.len_lo = (sizeof(mxcpc_mxpeg::SOF0) - 2) % 256;
00225 SOF0_Block.data_precision = 0x08;
00226 SOF0_Block.y_sz_hi = 0;
00227 SOF0_Block.y_sz_lo = 0;
00228 SOF0_Block.x_sz_hi = 0;
00229 SOF0_Block.x_sz_lo = 0;
00230 SOF0_Block.num_components = 3;
00231 SOF0_Block.components[0].component_id = 1;
00232 SOF0_Block.components[0].sampl_fact = 0x22;
00233 SOF0_Block.components[0].quant_tbl_no = 0;
00234 SOF0_Block.components[1].component_id = 2;
00235 SOF0_Block.components[1].sampl_fact = 0x11;
00236 SOF0_Block.components[1].quant_tbl_no = 1;
00237 SOF0_Block.components[2].component_id = 3;
00238 SOF0_Block.components[2].sampl_fact = 0x11;
00239 SOF0_Block.components[2].quant_tbl_no = 1;
00240
00241
00242 SOS_Block.ff = 0xff;
00243 SOS_Block.sos_marker = mxcpc_mxpeg::MarkerId_SOS;
00244 SOS_Block.sz_hi = (sizeof(mxcpc_mxpeg::SOS) - 2) / 256;
00245 SOS_Block.sz_lo = (sizeof(mxcpc_mxpeg::SOS) - 2) % 256;
00246 SOS_Block.comps_in_scan = 3;
00247 SOS_Block.components[0].comp_id = 1;
00248 SOS_Block.components[0].td_ta = 0x00;
00249 SOS_Block.components[1].comp_id = 2;
00250 SOS_Block.components[1].td_ta = 0x11;
00251 SOS_Block.components[2].comp_id = 3;
00252 SOS_Block.components[2].td_ta = 0x11;
00253 SOS_Block.Ss = 0x00;
00254 SOS_Block.Se = 0x3f;
00255 SOS_Block.Ah_Al = 0x00;
00256 }
00257
00258
00259 mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00260 ::~mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly() {
00261
00262 delete HuffmanTree_Y_DC;
00263 delete HuffmanTree_Y_AC;
00264 delete HuffmanTree_UV_DC;
00265 delete HuffmanTree_UV_AC;
00266
00267 delete[] CoeffBuffer;
00268 delete[] HuffmanEncoderBuffer;
00269 }
00270
00271
00272
00273 const char *mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00274 ::getAccelerationTypeString(void) {
00275
00276 return("none");
00277 }
00278
00279
00280 void mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00281 ::setYQuantizationTable(unsigned char *data_bytes) {
00282
00283 int i;
00284
00285 for(i = 0; i < 64; i++) QuantizationTable_Y[ZigZagMap[i]] = *data_bytes++;
00286 }
00287
00288
00289 void mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00290 ::setUVQuantizationTable(unsigned char *data_bytes) {
00291
00292 int i;
00293
00294 for(i = 0; i < 64; i++) QuantizationTable_UV[ZigZagMap[i]] = *data_bytes++;
00295 }
00296
00297
00298 void mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00299 ::performScanSweep(mxcpcFramewiseMxPEGDecoder::UndecodedFrameDescriptor
00300 *frame_descriptor) {
00301
00302
00303 const mxcpcHuffmanTree::Node *Huffman_DC_Roots[6] = {
00304 HuffmanTree_Y_DC->getRoot(),
00305 HuffmanTree_Y_DC->getRoot(),
00306 HuffmanTree_Y_DC->getRoot(),
00307 HuffmanTree_Y_DC->getRoot(),
00308 HuffmanTree_UV_DC->getRoot(),
00309 HuffmanTree_UV_DC->getRoot()
00310 },
00311 *Huffman_AC_Roots[6] = {
00312 HuffmanTree_Y_AC->getRoot(),
00313 HuffmanTree_Y_AC->getRoot(),
00314 HuffmanTree_Y_AC->getRoot(),
00315 HuffmanTree_Y_AC->getRoot(),
00316 HuffmanTree_UV_AC->getRoot(),
00317 HuffmanTree_UV_AC->getRoot()
00318 };
00319
00320
00321
00322 bool use_bitmask;
00323 int tilebits_left;
00324 unsigned char *tilebit_ptr, tilebit_mask;
00325 int x, y;
00326 bool next_tile_right_here;
00327 int tiles_to_write;
00328
00329
00330 const mxcpcHuffmanTree::Node *huffman_leaf_node;
00331 int additional_bit_num;
00332 int ac_coeffs_needed;
00333 int ac_coeffs_to_output;
00334
00335
00336 mxcpc::s16 dc_coeffs[3] = { 0, 0, 0};
00337 mxcpc::s16 *dc_coeff_ptrs[6] = { &dc_coeffs[0],
00338 &dc_coeffs[0],
00339 &dc_coeffs[0],
00340 &dc_coeffs[0],
00341 &dc_coeffs[1],
00342 &dc_coeffs[2]
00343 };
00344
00345
00346 int coeff_i;
00347
00348 mxcpc::s16 *sub_mcu_coeffs;
00349 mxcpc::u8 quantization_table_to_write[64];
00350 mxcpc::s16 *quant_coeff;
00351 const unsigned char *huffman_table_to_write;
00352 int huffman_table_to_write_size;
00353
00354 int i, j;
00355
00356 mxcpc::u8 write_buffer[10];
00357
00358
00359 mxcpc::s16 *coeff_buffer=0;
00360
00361
00362 if(!BackEnd) return;
00363
00364
00365 if( (frame_descriptor->TileNumX != TileNumX)
00366 || (frame_descriptor->TileNumY != TileNumY)) {
00367
00368 delete[] CoeffBuffer;
00369
00370 try {
00371
00372 CoeffBuffer = new mxcpc::s16[frame_descriptor->TileNumX
00373 * frame_descriptor->TileNumY
00374 * 6 * 64
00375 ];
00376
00377 TileNumX = frame_descriptor->TileNumX;
00378 TileNumY = frame_descriptor->TileNumY;
00379
00380 mxcpc::sendStatusMsg("JPG converter : reallocated coeff buffer");
00381
00382 } catch(std::bad_alloc) {
00383
00384 mxcpc::sendStatusMsg("JPG converter : "
00385 "reallocation of coeff buffer failed!");
00386
00387 CoeffBuffer = 0;
00388 TileNumX = TileNumY = 0;
00389 }
00390 }
00391
00392 if(!CoeffBuffer) {
00393 mxcpc::sendStatusMsg("JPG converter : CoeffBuffer == NULL!");
00394 BackEnd->errorEncountered();
00395 return;
00396 }
00397
00398
00399
00400 CurrentScanByte = frame_descriptor->ScanBytes;
00401 ScanMask = 128;
00402 ScanBytesLeft = frame_descriptor->ScanLength;
00403 if(!CurrentScanByte || !ScanBytesLeft) {
00404 BackEnd->errorEncountered();
00405 return;
00406 }
00407 tilebits_left = frame_descriptor->TileNumX * frame_descriptor->TileNumY;
00408 tilebit_ptr = frame_descriptor->TileBits;
00409 tilebit_mask = 128;
00410 x = -1;
00411 y = 0;
00412 next_tile_right_here = true;
00413 if(tilebit_ptr)
00414 use_bitmask = true;
00415 else
00416 use_bitmask = false;
00417
00418
00419
00420 while(tilebits_left) {
00421
00422
00423 x++;
00424 if(x == frame_descriptor->TileNumX) {
00425 x = 0;
00426 y++;
00427 }
00428
00429
00430 if(use_bitmask) {
00431 next_tile_right_here = (*tilebit_ptr & tilebit_mask) != 0;
00432 tilebit_mask /= 2;
00433 if(!tilebit_mask) {
00434 tilebit_mask = 128;
00435 tilebit_ptr++;
00436 }
00437 }
00438
00439
00440
00441 if(next_tile_right_here) {
00442
00443
00444 for(i = 0; i < 6; i++) {
00445
00446 coeff_buffer
00447 = &CoeffBuffer[y * TileNumX * 6*64 + x * 6*64 + i * 64];
00448
00449
00450
00451
00452 huffman_leaf_node = consumeHuffmanCodeword(Huffman_DC_Roots[i]);
00453
00454 if(!huffman_leaf_node) {
00455
00456 BackEnd->errorEncountered();
00457 mxcpc::sendStatusMsg("JPG converter : "
00458 "1) huffman_leaf_node DC == NULL");
00459 return;
00460 }
00461
00462
00463 additional_bit_num = (int)( (unsigned int)huffman_leaf_node->Value
00464 & (unsigned int)0x0f);
00465 if(additional_bit_num) {
00466 if(consumeAdditionalBits(additional_bit_num)) {
00467
00468 mxcpc::sendStatusMsg("JPG converter : Return val consumeAdditionalBits() == NULL");
00469 BackEnd->errorEncountered();
00470 return;
00471 }
00472 coeff_buffer[0] = CoeffInAdditionalBits;
00473 }
00474 else {
00475 coeff_buffer[0] = 0;
00476 }
00477
00478
00479 coeff_buffer[0] += *dc_coeff_ptrs[i];
00480 *dc_coeff_ptrs[i] = coeff_buffer[0];
00481
00482
00483
00484 coeff_i = 1;
00485 ac_coeffs_needed = 63;
00486 while(ac_coeffs_needed) {
00487
00488
00489 huffman_leaf_node = consumeHuffmanCodeword(Huffman_AC_Roots[i]);
00490 if(!huffman_leaf_node) {
00491
00492 mxcpc::sendStatusMsg("JPG converter : "
00493 "2)huffman_leaf_node AC == NULL");
00494 BackEnd->errorEncountered();
00495 return;
00496 }
00497
00498
00499 if(huffman_leaf_node->Value == 0x00) {
00500 while(ac_coeffs_needed) {
00501 coeff_buffer[ZigZagMap[coeff_i]] = 0;
00502 coeff_i++;
00503 ac_coeffs_needed--;
00504 }
00505 continue;
00506 }
00507
00508
00509 additional_bit_num = (int)( (unsigned int)huffman_leaf_node->Value
00510 & (unsigned int)0x0f);
00511 if(additional_bit_num) {
00512 if(consumeAdditionalBits(additional_bit_num)) {
00513 mxcpc::sendStatusMsg("JPG converter : "
00514 "return val consumeAdditionalBits() == "
00515 "NULL");
00516 BackEnd->errorEncountered();
00517 return;
00518 }
00519 }
00520 else
00521 CoeffInAdditionalBits = 0;
00522
00523
00524 ac_coeffs_to_output = huffman_leaf_node->Value/16 + 1;
00525 if(ac_coeffs_to_output > ac_coeffs_needed) {
00526 mxcpc::sendStatusMsg("too many AC coeffs!");
00527 BackEnd->errorEncountered();
00528 return;
00529 }
00530 for(j = 0; j < ac_coeffs_to_output-1; j++) {
00531 coeff_buffer[ZigZagMap[coeff_i]] = 0;
00532 coeff_i++;
00533 }
00534 coeff_buffer[ZigZagMap[coeff_i]] = CoeffInAdditionalBits;
00535 coeff_i++;
00536 if(coeff_i > 64) {
00537 mxcpc::sendStatusMsg("coeff buffer overflow!");
00538 BackEnd->errorEncountered();
00539 return;
00540 }
00541
00542 ac_coeffs_needed -= ac_coeffs_to_output;
00543 }
00544
00545 }
00546
00547
00548
00549 BackEnd->videoTileReceived();
00550 }
00551
00552 tilebits_left--;
00553 }
00554
00555
00556
00557 Receiver->beginFrame();
00558
00559
00560 write_buffer[0] = 0xff;
00561 write_buffer[1] = mxcpc_mxpeg::MarkerId_SOI;
00562 Receiver->receiveJPEGBytes(write_buffer, 2);
00563
00564
00565 Receiver->receiveJPEGBytes((mxcpc::u8 *)&APP0_Block,
00566 sizeof(mxcpc_mxpeg::APP0));
00567
00568
00569 for(i = 0; i < 2; i++) {
00570 write_buffer[0] = 0xff;
00571 write_buffer[1] = mxcpc_mxpeg::MarkerId_DQT;
00572 write_buffer[2] = 0;
00573 write_buffer[3] = 67;
00574 write_buffer[4] = i;
00575 Receiver->receiveJPEGBytes(write_buffer, 5);
00576
00577 if(!i) quant_coeff = QuantizationTable_Y;
00578 else quant_coeff = QuantizationTable_UV;
00579 for(j = 0; j < 64; j++)
00580 quantization_table_to_write[ZigZag_StoreMap[j]]
00581 = ((mxcpc::u8)*quant_coeff++);
00582 Receiver->receiveJPEGBytes(quantization_table_to_write, 64);
00583 }
00584
00585
00586 SOF0_Block.x_sz_hi = frame_descriptor->Width / 256;
00587 SOF0_Block.x_sz_lo = frame_descriptor->Width % 256;
00588 SOF0_Block.y_sz_hi = frame_descriptor->Height / 256;
00589 SOF0_Block.y_sz_lo = frame_descriptor->Height % 256;
00590 Receiver->receiveJPEGBytes((mxcpc::u8 *)&SOF0_Block,
00591 sizeof(mxcpc_mxpeg::SOF0));
00592
00593
00594 for(i = 0; i < 4; i++) {
00595 write_buffer[0] = 0xff;
00596 write_buffer[1] = mxcpc_mxpeg::MarkerId_DHT;
00597 if(i == 0) {
00598 write_buffer[4] = 0x00;
00599 huffman_table_to_write = DefaultHuffmanTable_Y_DC;
00600 huffman_table_to_write_size = DefaultHuffmanTable_Y_DC_Size;
00601 }
00602 else if(i == 1) {
00603 write_buffer[4] = 0x10;
00604 huffman_table_to_write = DefaultHuffmanTable_Y_AC;
00605 huffman_table_to_write_size = DefaultHuffmanTable_Y_AC_Size;
00606 }
00607 else if(i == 2) {
00608 write_buffer[4] = 0x01;
00609 huffman_table_to_write = DefaultHuffmanTable_UV_DC;
00610 huffman_table_to_write_size = DefaultHuffmanTable_UV_DC_Size;
00611 }
00612 else {
00613 write_buffer[4] = 0x11;
00614 huffman_table_to_write = DefaultHuffmanTable_UV_AC;
00615 huffman_table_to_write_size = DefaultHuffmanTable_UV_AC_Size;
00616 }
00617 write_buffer[2] = (huffman_table_to_write_size + 3) / 256;
00618 write_buffer[3] = (huffman_table_to_write_size + 3) % 256;
00619 Receiver->receiveJPEGBytes(write_buffer, 5);
00620 Receiver->receiveJPEGBytes((mxcpc::u8 *)huffman_table_to_write,
00621 huffman_table_to_write_size);
00622 }
00623
00624
00625 Receiver->receiveJPEGBytes((mxcpc::u8 *)&SOS_Block,
00626 sizeof(mxcpc_mxpeg::SOS));
00627
00628
00629 for(i=0; i < 3; i++) dc_coeffs[i] = 0;
00630 dc_coeff_ptrs[0] = &dc_coeffs[0];
00631 dc_coeff_ptrs[1] = &dc_coeffs[0];
00632 dc_coeff_ptrs[2] = &dc_coeffs[0];
00633 dc_coeff_ptrs[3] = &dc_coeffs[0];
00634 dc_coeff_ptrs[4] = &dc_coeffs[1];
00635 dc_coeff_ptrs[5] = &dc_coeffs[2];
00636
00637
00638 FoldedHuffTbl_DC_AC* huff_code_table_list[6];
00639
00640
00641 huff_code_table_list[0] = &Huff_Y_UV[0];
00642 huff_code_table_list[1] = &Huff_Y_UV[0];
00643 huff_code_table_list[2] = &Huff_Y_UV[0];
00644 huff_code_table_list[3] = &Huff_Y_UV[0];
00645
00646
00647 huff_code_table_list[4] = &Huff_Y_UV[1];
00648 huff_code_table_list[5] = &Huff_Y_UV[1];
00649
00650
00651 sub_mcu_coeffs = CoeffBuffer;
00652 tiles_to_write = TileNumX * TileNumY;
00653
00654 int nb_of_bytes_to_write = 0;
00655 while(tiles_to_write) {
00656
00657
00658 for(i = 0; i < 6; i++) {
00659 encodeSubMCUTiles(sub_mcu_coeffs,
00660 dc_coeff_ptrs[i],
00661 huff_code_table_list[i],
00662 &HuffmanBufferState);
00663 sub_mcu_coeffs += 64;
00664 }
00665
00666 tiles_to_write--;
00667 }
00668
00669
00670 shutDownHuffAccu();
00671
00672
00673 nb_of_bytes_to_write
00674 = HuffmanBufferState.buf_current_w_pos - HuffmanBufferState.buf_start;
00675 Receiver->receiveJPEGBytes(HuffmanBufferState.buf_start,
00676 nb_of_bytes_to_write);
00677
00678
00679 resetHuffmanEncoderBufferState();
00680
00681
00682 write_buffer[0] = 0xff;
00683 write_buffer[1] = mxcpc_mxpeg::MarkerId_EOI;
00684 Receiver->receiveJPEGBytes(write_buffer, 2);
00685
00686
00687
00688 Receiver->endFrame();
00689
00690 FramesProcessed++;
00691 }
00692
00693
00694
00695
00696
00697 void mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00698 ::calcFoldedHuffTables(void){
00699
00700 int y_uv;
00701
00702 static int firstcall = 0;
00703 if (firstcall) return;
00704
00705 firstcall++;
00706
00707
00708 for (y_uv = 0; y_uv < 2; y_uv++) {
00709
00710
00711 generateHuffTables1(
00712
00713
00714 &HuffTbl_Y_UV_DC[y_uv].bits_dc[0],
00715
00716
00717 &HuffTbl_Y_UV_DC[y_uv].val_dc[0],
00718
00719
00720 0,
00721 &Huff_Y_UV[y_uv].dc_tbl[0]
00722 );
00723
00724
00725 generateHuffTables1(
00726
00727
00728 &HuffTbl_Y_UV_AC[y_uv].bits_ac[0],
00729
00730
00731 &HuffTbl_Y_UV_AC[y_uv].val_ac[0],
00732
00733
00734 1,
00735
00736 &Huff_Y_UV[y_uv].ac_tbl[0]
00737 );
00738 }
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 void mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly::generateHuffTables1(
00760 const mxcpc::u8 * bits_tbl_off1,
00761 const mxcpc::u8 * val_tbl,
00762 int swap_symbol,
00763 HuffCodeTblEntry * folded_tbl_p
00764 ) {
00765
00766 int len, codes_of_len, mantissa_len;
00767
00768 int code = 0;
00769 for(len = 1; len <= 16; len ++) {
00770
00771 for(codes_of_len = 1;
00772 codes_of_len <= bits_tbl_off1[len - 1];
00773 codes_of_len++) {
00774
00775 int symbol = *val_tbl++;
00776
00777 mantissa_len = symbol & 0xf;
00778
00779
00780 if(swap_symbol) {
00781 symbol = (symbol >> 4) + ((symbol & 0xf) << 4);
00782 }
00783 folded_tbl_p[symbol].code_msk = code << mantissa_len;
00784 folded_tbl_p[symbol].fill_0bit = 0;
00785 folded_tbl_p[symbol].bit_len = len + mantissa_len;
00786 code++;
00787 }
00788
00789 code <<= 1;
00790 }
00791 }
00792
00793
00794
00795
00796
00797 void mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00798 ::initHuffmanEncoderBufferState() {
00799
00800 HuffmanBufferState.buf_start = &HuffmanEncoderBuffer[0];
00801 HuffmanBufferState.buf_current_w_pos = &HuffmanEncoderBuffer[0];
00802 HuffmanBufferState.buf_end1
00803 = &HuffmanEncoderBuffer[
00804 MXCPC_FRAMEWISEMXPEGSCANTOJPEGCONVERTER_BITSTREAM_BUFFSIZE + 1
00805 ];
00806
00807 HuffmanBufferState.huf_accu = 0;
00808 HuffmanBufferState.huf_bits_used = 0;
00809 }
00810
00811
00812
00813
00814
00815 void mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly
00816 ::resetHuffmanEncoderBufferState() {
00817
00818 HuffmanBufferState.buf_start = &HuffmanEncoderBuffer[0];
00819 HuffmanBufferState.buf_current_w_pos = &HuffmanEncoderBuffer[0];
00820
00821 HuffmanBufferState.huf_accu = 0;
00822 HuffmanBufferState.huf_bits_used = 0;
00823 }
00824