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