00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "precomp.h"
00026
00027 #include <stdio.h>
00028 #include <string.h>
00029
00030 #ifndef __JPEGBASE_H__
00031 #include "jpegbase.h"
00032 #endif
00033 #ifndef __ENCODER_H__
00034 #include "encoder.h"
00035 #endif
00036
00037
00038
00039
00040 CJPEGEncoder::CJPEGEncoder(void)
00041 {
00042 m_src.p.Data8u = 0;
00043 m_src.width = 0;
00044 m_src.height = 0;
00045 m_src.nChannels = 0;
00046 m_src.lineStep = 0;
00047
00048 m_dst.pData = 0;
00049 m_dst.DataLen = 0;
00050 m_dst.currPos = 0;
00051
00052 m_jpeg_ncomp = 0;
00053 m_jpeg_precision = 8;
00054 m_jpeg_sampling = JS_444;
00055 m_jpeg_color = JC_UNKNOWN;
00056 m_jpeg_quality = 100;
00057 m_jpeg_restart_interval = 0;
00058 m_jpeg_mode = JPEG_BASELINE;
00059
00060 m_numxMCU = 0;
00061 m_numyMCU = 0;
00062 m_mcuWidth = 0;
00063 m_mcuHeight = 0;
00064
00065 m_ccWidth = 0;
00066 m_ccHeight = 0;
00067 m_xPadding = 0;
00068 m_yPadding = 0;
00069
00070 m_restarts_to_go = 0;
00071 m_next_restart_num = 0;
00072
00073 m_scan_count = 0;
00074 m_scan_script = 0;
00075 m_coefbuf = 0;
00076
00077 m_ss = 0;
00078 m_se = 63;
00079 m_ah = 0;
00080 m_al = 0;
00081
00082 m_predictor = 1;
00083 m_pt = 0;
00084
00085 m_ccomp[0] = 0;
00086 m_ccomp[1] = 0;
00087 m_ccomp[2] = 0;
00088 m_ccomp[3] = 0;
00089
00090 return;
00091 }
00092
00093
00094 CJPEGEncoder::~CJPEGEncoder(void)
00095 {
00096 Clean();
00097 return;
00098 }
00099
00100
00101 JERRCODE CJPEGEncoder::Clean(void)
00102 {
00103 for(int i = 0; i < m_jpeg_ncomp; i++)
00104 {
00105 delete m_ccomp[i];
00106 m_ccomp[i] = 0;
00107 }
00108
00109 if(0 != m_scan_script)
00110 {
00111 delete[] m_scan_script;
00112 m_scan_script = 0;
00113 }
00114
00115 if(0 != m_coefbuf)
00116 {
00117 ippFree(m_coefbuf);
00118 m_coefbuf = 0;
00119 }
00120
00121 m_src.p.Data8u = 0;
00122 m_src.width = 0;
00123 m_src.height = 0;
00124 m_src.nChannels = 0;
00125 m_src.lineStep = 0;
00126
00127 m_dst.pData = 0;
00128 m_dst.DataLen = 0;
00129 m_dst.currPos = 0;
00130
00131 m_jpeg_ncomp = 0;
00132 m_jpeg_sampling = JS_444;
00133 m_jpeg_color = JC_UNKNOWN;
00134 m_jpeg_quality = 100;
00135 m_jpeg_restart_interval = 0;
00136 m_jpeg_mode = JPEG_BASELINE;
00137
00138 m_numxMCU = 0;
00139 m_numyMCU = 0;
00140 m_mcuWidth = 0;
00141 m_mcuHeight = 0;
00142
00143 m_ccWidth = 0;
00144 m_ccHeight = 0;
00145 m_xPadding = 0;
00146 m_yPadding = 0;
00147
00148 m_restarts_to_go = 0;
00149 m_next_restart_num = 0;
00150
00151 m_scan_count = 0;
00152
00153 return JPEG_OK;
00154 }
00155
00156
00157 JERRCODE CJPEGEncoder::SetSource(
00158 Ipp8u* pSrc,
00159 int srcStep,
00160 IppiSize srcSize,
00161 int srcChannels,
00162 JCOLOR srcColor)
00163 {
00164 m_src.p.Data8u = pSrc;
00165 m_src.lineStep = srcStep;
00166 m_src.width = srcSize.width;
00167 m_src.height = srcSize.height;
00168 m_src.nChannels = srcChannels;
00169 m_src.color = srcColor;
00170
00171 return JPEG_OK;
00172 }
00173
00174
00175 JERRCODE CJPEGEncoder::SetDestination(
00176 Ipp8u* pDst,
00177 int dstSize,
00178 int dstQuality,
00179 JSS dstSampling,
00180 JCOLOR dstColor,
00181 JMODE dstMode,
00182 int dstRestartInt)
00183 {
00184 m_dst.pData = pDst;
00185 m_dst.DataLen = dstSize;
00186 m_dst.currPos = 0;
00187
00188 m_jpeg_quality = dstQuality;
00189 m_jpeg_sampling = dstSampling;
00190 m_jpeg_color = dstColor;
00191 m_jpeg_mode = dstMode;
00192 m_jpeg_restart_interval = dstRestartInt;
00193
00194 m_restarts_to_go = m_jpeg_restart_interval;
00195
00196 if(JPEG_LOSSLESS == m_jpeg_mode)
00197 {
00198 m_mcuWidth = 1;
00199 m_mcuHeight = 1;
00200 }
00201 else
00202 {
00203 m_mcuWidth = (m_jpeg_sampling == JS_444) ? 8 : 16;
00204 m_mcuHeight = (m_jpeg_sampling == JS_411) ? 16 : 8;
00205 }
00206
00207 m_numxMCU = (m_src.width + (m_mcuWidth - 1)) / m_mcuWidth;
00208 m_numyMCU = (m_src.height + (m_mcuHeight - 1)) / m_mcuHeight;
00209
00210 return JPEG_OK;
00211 }
00212
00213
00214 JERRCODE CJPEGEncoder::WriteSOI(void)
00215 {
00216 TRC0("-> WriteSOI");
00217
00218 if(m_dst.currPos + 2 >= m_dst.DataLen)
00219 {
00220 LOG0("Error: buffer too small");
00221 return JPEG_BUFF_TOO_SMALL;
00222 }
00223
00224 TRC1(" emit marker ",JM_SOI);
00225
00226 m_dst._WRITE_WORD(0xff00 | JM_SOI);
00227
00228 return JPEG_OK;
00229 }
00230
00231
00232 JERRCODE CJPEGEncoder::WriteEOI(void)
00233 {
00234 TRC0("-> WriteEOI");
00235
00236 if(m_dst.currPos + 2 >= m_dst.DataLen)
00237 {
00238 LOG0("Error: buffer too small");
00239 return JPEG_BUFF_TOO_SMALL;
00240 }
00241
00242 TRC1("emit marker ",JM_EOI);
00243
00244 m_dst._WRITE_WORD(0xff00 | JM_EOI);
00245
00246 return JPEG_OK;
00247 }
00248
00249
00250 JERRCODE CJPEGEncoder::WriteAPP0(void)
00251 {
00252 int len;
00253
00254 TRC0("-> WriteAPP0");
00255
00256 len = 2 + 5 + 2 + 1 + 2 + 2 + 1 + 1;
00257
00258 if(m_dst.currPos + len >= m_dst.DataLen)
00259 {
00260 LOG0("Error: buffer too small");
00261 return JPEG_BUFF_TOO_SMALL;
00262 }
00263
00264 TRC1(" emit marker ",JM_APP0);
00265 TRC1(" length ",len);
00266
00267 m_dst._WRITE_WORD(0xff00 | JM_APP0);
00268 m_dst._WRITE_WORD(len);
00269
00270
00271 m_dst._WRITE_BYTE('J');
00272 m_dst._WRITE_BYTE('F');
00273 m_dst._WRITE_BYTE('I');
00274 m_dst._WRITE_BYTE('F');
00275 m_dst._WRITE_BYTE(0);
00276
00277
00278 m_dst._WRITE_WORD(0x0102);
00279
00280
00281 m_dst._WRITE_BYTE(0);
00282
00283
00284 m_dst._WRITE_WORD(1);
00285
00286
00287 m_dst._WRITE_WORD(1);
00288
00289
00290 m_dst._WRITE_BYTE(0);
00291 m_dst._WRITE_BYTE(0);
00292
00293 return JPEG_OK;
00294 }
00295
00296
00297 JERRCODE CJPEGEncoder::WriteAPP14(void)
00298 {
00299 int len;
00300
00301 TRC0("-> WriteAPP14");
00302
00303 len = 2 + 5 + 2 + 2 + 2 + 1;
00304
00305 if(m_dst.currPos + len >= m_dst.DataLen)
00306 {
00307 LOG0("Error: buffer too small");
00308 return JPEG_BUFF_TOO_SMALL;
00309 }
00310
00311 TRC1(" emit marker ",JM_APP14);
00312 TRC1(" length ",len);
00313
00314 m_dst._WRITE_WORD(0xff00 | JM_APP14);
00315 m_dst._WRITE_WORD(len);
00316
00317
00318 m_dst._WRITE_BYTE('A');
00319 m_dst._WRITE_BYTE('d');
00320 m_dst._WRITE_BYTE('o');
00321 m_dst._WRITE_BYTE('b');
00322 m_dst._WRITE_BYTE('e');
00323
00324
00325 m_dst._WRITE_WORD(100);
00326
00327
00328 m_dst._WRITE_WORD(0);
00329
00330
00331 m_dst._WRITE_WORD(0);
00332
00333 switch(m_jpeg_color)
00334 {
00335 case JC_YCBCR:
00336 m_dst._WRITE_BYTE(1);
00337 break;
00338 case JC_YCCK:
00339 m_dst._WRITE_BYTE(2);
00340 break;
00341 default:
00342 m_dst._WRITE_BYTE(0);
00343 break;
00344 }
00345
00346 return JPEG_OK;
00347 }
00348
00349
00350 JERRCODE CJPEGEncoder::WriteCOM(
00351 char* comment)
00352 {
00353 int len;
00354 char* ptr;
00355
00356 TRC0("-> WriteCOM");
00357
00358 if(comment != 0)
00359 {
00360 len = (int)strlen(comment) + 1;
00361 ptr = comment;
00362 }
00363 else
00364 {
00365 char buf[64];
00366 ptr = &buf[0];
00367 const IppLibraryVersion* jv = ippjGetLibVersion();
00368 sprintf(ptr,"JPEG encoder based on ippJP [%d.%d.%d] - %s",
00369 jv->major,
00370 jv->minor,
00371 jv->build,
00372 jv->BuildDate);
00373
00374 len = (int)strlen(ptr) + 1;
00375 }
00376
00377 len += 2;
00378
00379 if(m_dst.currPos + len >= m_dst.DataLen)
00380 {
00381 LOG0("Error: buffer too small");
00382 return JPEG_BUFF_TOO_SMALL;
00383 }
00384
00385 TRC1(" emit marker ",JM_COM);
00386 TRC1(" length ",len);
00387
00388 m_dst._WRITE_WORD(0xff00 | JM_COM);
00389 m_dst._WRITE_WORD(len);
00390
00391 for(int i = 0; i < len - 2; i++)
00392 {
00393 m_dst._WRITE_BYTE(ptr[i]);
00394 }
00395
00396 return JPEG_OK;
00397 }
00398
00399
00400 JERRCODE CJPEGEncoder::WriteDQT(
00401 CJPEGEncoderQuantTable* qtbl)
00402 {
00403 int i;
00404 int len;
00405
00406 TRC0("-> WriteDQT");
00407
00408 len = DCTSIZE2 + 2 + 1;
00409
00410 if(m_dst.currPos + len >= m_dst.DataLen)
00411 {
00412 LOG0("Error: buffer too small");
00413 return JPEG_BUFF_TOO_SMALL;
00414 }
00415
00416 TRC1(" emit marker ",JM_DQT);
00417 TRC1(" length ",len);
00418
00419 m_dst._WRITE_WORD(0xff00 | JM_DQT);
00420 m_dst._WRITE_WORD(len);
00421
00422
00423 m_dst._WRITE_BYTE((qtbl->m_precision << 4) | qtbl->m_id);
00424
00425 TRC1(" id ",qtbl->m_id);
00426 TRC1(" precision ",qtbl->m_precision);
00427
00428 TRC(endl);
00429 for(i = 0; i < DCTSIZE2; i++)
00430 {
00431 TRC(" ");
00432 TRC((int)qtbl->m_raw[i]);
00433 if(i % 8 == 7)
00434 {
00435 TRC(endl);
00436 }
00437 }
00438 TRC(endl);
00439
00440 for(i = 0; i < DCTSIZE2; i++)
00441 {
00442 m_dst._WRITE_BYTE(qtbl->m_raw[i]);
00443 }
00444
00445 return JPEG_OK;
00446 }
00447
00448
00449 JERRCODE CJPEGEncoder::WriteDHT(
00450 CJPEGEncoderHuffmanTable* htbl)
00451 {
00452 int i;
00453 int len;
00454 int htbl_len;
00455
00456 TRC0("-> WriteDHT");
00457
00458 for(htbl_len = 0, i = 0; i < 16; i++)
00459 {
00460 htbl_len += htbl->m_bits[i];
00461 }
00462
00463 len = 16 + htbl_len + 2 + 1;
00464
00465 if(m_dst.currPos + len >= m_dst.DataLen)
00466 {
00467 LOG0("Error: buffer too small");
00468 return JPEG_BUFF_TOO_SMALL;
00469 }
00470
00471 TRC1(" emit marker ",JM_DHT);
00472 TRC1(" length ",len);
00473
00474 m_dst._WRITE_WORD(0xff00 | JM_DHT);
00475 m_dst._WRITE_WORD(len);
00476
00477 m_dst._WRITE_BYTE((htbl->m_hclass << 4) | htbl->m_id);
00478
00479 TRC1(" id ",htbl->m_id);
00480 TRC1(" class ",htbl->m_hclass);
00481
00482 for(i = 0; i < 16; i++)
00483 {
00484 m_dst._WRITE_BYTE(htbl->m_bits[i]);
00485 }
00486
00487 for(i = 0; i < htbl_len; i++)
00488 {
00489 m_dst._WRITE_BYTE(htbl->m_vals[i]);
00490 }
00491
00492 return JPEG_OK;
00493 }
00494
00495
00496 JERRCODE CJPEGEncoder::WriteSOF0(void)
00497 {
00498 int len;
00499
00500 TRC0("-> WriteSOF0");
00501
00502 len = 8 + m_jpeg_ncomp * 3;
00503
00504 if(m_dst.currPos + len >= m_dst.DataLen)
00505 {
00506 LOG0("Error: buffer too small");
00507 return JPEG_BUFF_TOO_SMALL;
00508 }
00509
00510 TRC1(" emit marker ",JM_SOF0);
00511 TRC1(" length ",len);
00512
00513 m_dst._WRITE_WORD(0xff00 | JM_SOF0);
00514 m_dst._WRITE_WORD(len);
00515
00516
00517 m_dst._WRITE_BYTE(8);
00518
00519 m_dst._WRITE_WORD(m_src.height);
00520 m_dst._WRITE_WORD(m_src.width);
00521
00522 m_dst._WRITE_BYTE(m_jpeg_ncomp);
00523
00524 for(int i = 0; i < m_jpeg_ncomp; i++)
00525 {
00526 m_dst._WRITE_BYTE(i);
00527 m_dst._WRITE_BYTE((m_ccomp[i]->m_hsampling << 4) | m_ccomp[i]->m_vsampling);
00528 m_dst._WRITE_BYTE(m_ccomp[i]->m_q_selector);
00529 }
00530
00531 return JPEG_OK;
00532 }
00533
00534
00535 JERRCODE CJPEGEncoder::WriteSOF1(void)
00536 {
00537 int len;
00538
00539 TRC0("-> WriteSOF1");
00540
00541 len = 8 + m_jpeg_ncomp * 3;
00542
00543 if(m_dst.currPos + len >= m_dst.DataLen)
00544 {
00545 LOG0("Error: buffer too small");
00546 return JPEG_BUFF_TOO_SMALL;
00547 }
00548
00549 TRC1(" emit marker ",JM_SOF1);
00550 TRC1(" length ",sof1_len);
00551
00552 m_dst._WRITE_WORD(0xff00 | JM_SOF1);
00553 m_dst._WRITE_WORD(len);
00554
00555
00556 m_dst._WRITE_BYTE(8);
00557
00558 m_dst._WRITE_WORD(m_src.height);
00559 m_dst._WRITE_WORD(m_src.width);
00560
00561 m_dst._WRITE_BYTE(m_jpeg_ncomp);
00562
00563 for(int i = 0; i < m_jpeg_ncomp; i++)
00564 {
00565 m_dst._WRITE_BYTE(i);
00566 m_dst._WRITE_BYTE((m_ccomp[i]->m_hsampling << 4) | m_ccomp[i]->m_vsampling);
00567 m_dst._WRITE_BYTE(m_ccomp[i]->m_q_selector);
00568 }
00569
00570 return JPEG_OK;
00571 }
00572
00573
00574 JERRCODE CJPEGEncoder::WriteSOF2(void)
00575 {
00576 int len;
00577
00578 TRC0("-> WriteSOF2");
00579
00580 len = 8 + m_jpeg_ncomp * 3;
00581
00582 if(m_dst.currPos + len >= m_dst.DataLen)
00583 {
00584 LOG0("Error: buffer too small");
00585 return JPEG_BUFF_TOO_SMALL;
00586 }
00587
00588 TRC1(" emit marker ",JM_SOF2);
00589 TRC1(" length ",len);
00590
00591 m_dst._WRITE_WORD(0xff00 | JM_SOF2);
00592 m_dst._WRITE_WORD(len);
00593
00594
00595 m_dst._WRITE_BYTE(8);
00596
00597 m_dst._WRITE_WORD(m_src.height);
00598 m_dst._WRITE_WORD(m_src.width);
00599
00600 TRC1(" height ",m_src.height);
00601 TRC1(" width ",m_src.width);
00602
00603 m_dst._WRITE_BYTE(m_jpeg_ncomp);
00604
00605 for(int i = 0; i < m_jpeg_ncomp; i++)
00606 {
00607 m_dst._WRITE_BYTE(i);
00608 m_dst._WRITE_BYTE((m_ccomp[i]->m_hsampling << 4) | m_ccomp[i]->m_vsampling);
00609 m_dst._WRITE_BYTE(m_ccomp[i]->m_q_selector);
00610
00611 TRC1(" id ",i);
00612 TRC1(" h_sampling ",m_ccomp[i]->m_hsampling);
00613 TRC1(" v_sampling ",m_ccomp[i]->m_vsampling);
00614 TRC1(" q_selector ",m_ccomp[i]->m_q_selector);
00615 }
00616
00617 return JPEG_OK;
00618 }
00619
00620
00621 JERRCODE CJPEGEncoder::WriteSOF3(void)
00622 {
00623 int len;
00624
00625 TRC0("-> WriteSOF3");
00626
00627 len = 8 + m_jpeg_ncomp * 3;
00628
00629 if(m_dst.currPos + len >= m_dst.DataLen)
00630 {
00631 LOG0("Error: buffer too small");
00632 return JPEG_BUFF_TOO_SMALL;
00633 }
00634
00635 TRC1(" emit marker ",JM_SOF3);
00636 TRC1(" length ",len);
00637
00638 m_dst._WRITE_WORD(0xff00 | JM_SOF3);
00639 m_dst._WRITE_WORD(len);
00640
00641
00642 m_dst._WRITE_BYTE(m_jpeg_precision);
00643
00644 m_dst._WRITE_WORD(m_src.height);
00645 m_dst._WRITE_WORD(m_src.width);
00646
00647 m_dst._WRITE_BYTE(m_jpeg_ncomp);
00648
00649 for(int i = 0; i < m_jpeg_ncomp; i++)
00650 {
00651 m_dst._WRITE_BYTE(i);
00652 m_dst._WRITE_BYTE((m_ccomp[i]->m_hsampling << 4) | m_ccomp[i]->m_vsampling);
00653 m_dst._WRITE_BYTE(m_ccomp[i]->m_q_selector);
00654 }
00655
00656 return JPEG_OK;
00657 }
00658
00659
00660 JERRCODE CJPEGEncoder::WriteDRI(
00661 int restart_interval)
00662 {
00663 int len;
00664
00665 TRC0("-> WriteDRI");
00666
00667 len = 2 + 2;
00668
00669 if(m_dst.currPos + len >= m_dst.DataLen)
00670 {
00671 LOG0("Error: buffer too small");
00672 return JPEG_BUFF_TOO_SMALL;
00673 }
00674
00675 TRC1(" emit marker ",JM_DRI);
00676 TRC1(" length ",len);
00677
00678 m_dst._WRITE_WORD(0xff00 | JM_DRI);
00679 m_dst._WRITE_WORD(len);
00680
00681
00682 m_dst._WRITE_WORD(restart_interval);
00683
00684 m_restarts_to_go = m_jpeg_restart_interval;
00685 m_next_restart_num = 0;
00686
00687 TRC1(" restart ",restart_interval);
00688
00689 return JPEG_OK;
00690 }
00691
00692
00693 JERRCODE CJPEGEncoder::WriteRST(
00694 int next_restart_num)
00695 {
00696 int len;
00697
00698 TRC0("-> WriteRST");
00699
00700 len = 2;
00701
00702 if(m_dst.currPos + len >= m_dst.DataLen)
00703 {
00704 LOG0("Error: buffer too small");
00705 return JPEG_BUFF_TOO_SMALL;
00706 }
00707
00708 TRC1(" emit marker ",JM_RST0 + next_restart_num);
00709 TRC1(" RST ",0xfff0 | (JM_RST0 + next_restart_num));
00710
00711
00712 m_dst._WRITE_BYTE(0xff);
00713 m_dst._WRITE_BYTE(0xff00 | (JM_RST0 + next_restart_num));
00714
00715
00716 m_next_restart_num = (next_restart_num + 1) & 7;
00717
00718 return JPEG_OK;
00719 }
00720
00721
00722 JERRCODE CJPEGEncoder::ProcessRestart(
00723 int id[MAX_COMPS_PER_SCAN],
00724 int Ss,
00725 int Se,
00726 int Ah,
00727 int Al)
00728 {
00729 JERRCODE jerr;
00730 IppStatus status = ippStsNoErr;
00731
00732 TRC0("-> ProcessRestart");
00733
00734
00735 switch(m_jpeg_mode)
00736 {
00737 case JPEG_BASELINE:
00738 status = ippiEncodeHuffman8x8_JPEG_16s1u_C1(
00739 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,0,0,0,m_state,1);
00740 break;
00741
00742 case JPEG_PROGRESSIVE:
00743 if(Ss == 0 && Se == 0)
00744 {
00745
00746 if(Ah == 0)
00747 {
00748 status = ippiEncodeHuffman8x8_DCFirst_JPEG_16s1u_C1(
00749 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,0,0,0,m_state,1);
00750 }
00751 else
00752 {
00753 status = ippiEncodeHuffman8x8_DCRefine_JPEG_16s1u_C1(
00754 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,0,m_state,1);
00755 }
00756 }
00757 else
00758 {
00759
00760 IppiEncodeHuffmanSpec* actbl = m_actbl[m_ccomp[id[0]]->m_ac_selector];
00761
00762 if(Ah == 0)
00763 {
00764 status = ippiEncodeHuffman8x8_ACFirst_JPEG_16s1u_C1(
00765 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,Ss,Se,Al,actbl,m_state,1);
00766 }
00767 else
00768 {
00769 status = ippiEncodeHuffman8x8_ACRefine_JPEG_16s1u_C1(
00770 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,Ss,Se,Al,actbl,m_state,1);
00771 }
00772 }
00773 break;
00774
00775 case JPEG_LOSSLESS:
00776 status = ippiEncodeHuffmanOne_JPEG_16s1u_C1(
00777 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,0,m_state,1);
00778 break;
00779 }
00780
00781 if(ippStsNoErr > status)
00782 {
00783 LOG1("IPP Error: ippiEncodeHuffman8x8_JPEG_16s1u_C1() failed - ",status);
00784 return JPEG_INTERNAL_ERROR;
00785 }
00786
00787 status = ippiEncodeHuffmanStateInit_JPEG_8u(m_state);
00788 if(ippStsNoErr != status)
00789 {
00790 return JPEG_INTERNAL_ERROR;
00791 }
00792
00793 jerr = WriteRST(m_next_restart_num);
00794 if(JPEG_OK != jerr)
00795 {
00796 LOG1("IPP Error: WriteRST() failed - ",jerr);
00797 return JPEG_INTERNAL_ERROR;
00798 }
00799
00800 for(int c = 0; c < m_jpeg_ncomp; c++)
00801 {
00802 m_ccomp[c]->m_lastDC = 0;
00803 }
00804
00805 m_restarts_to_go = m_jpeg_restart_interval;
00806
00807 return JPEG_OK;
00808 }
00809
00810
00811 JERRCODE CJPEGEncoder::ProcessRestart(
00812 int stat[2][256],
00813 int id[MAX_COMPS_PER_SCAN],
00814 int Ss,
00815 int Se,
00816 int Ah,
00817 int Al)
00818 {
00819 IppStatus status;
00820
00821 TRC0("-> ProcessRestart");
00822
00823
00824 if(JPEG_PROGRESSIVE == m_jpeg_mode)
00825 {
00826 if(Ss == 0 && Se == 0)
00827 {
00828
00829
00830 }
00831 else
00832 {
00833
00834
00835 if(Ah == 0)
00836 {
00837 status = ippiGetHuffmanStatistics8x8_ACFirst_JPEG_16s_C1(
00838 0,&stat[m_ccomp[id[0]]->m_ac_selector][0],Ss,Se,Al,m_state,1);
00839
00840 if(ippStsNoErr > status)
00841 {
00842 LOG1("IPP Error: ippiGetHuffmanStatistics8x8_ACFirst_JPEG_16s_C1() failed - ",status);
00843 return JPEG_INTERNAL_ERROR;
00844 }
00845 }
00846 else
00847 {
00848 status = ippiGetHuffmanStatistics8x8_ACRefine_JPEG_16s_C1(
00849 0,&stat[m_ccomp[id[0]]->m_ac_selector][0],Ss,Se,Al,m_state,1);
00850
00851 if(ippStsNoErr > status)
00852 {
00853 LOG1("IPP Error: ippiGetHuffmanStatistics8x8_ACRefine_JPEG_16s_C1() failed - ",status);
00854 return JPEG_INTERNAL_ERROR;
00855 }
00856 }
00857 }
00858 }
00859
00860 status = ippiEncodeHuffmanStateInit_JPEG_8u(m_state);
00861 if(ippStsNoErr != status)
00862 {
00863 return JPEG_INTERNAL_ERROR;
00864 }
00865
00866 for(int c = 0; c < m_jpeg_ncomp; c++)
00867 {
00868 m_ccomp[c]->m_lastDC = 0;
00869 }
00870
00871 m_restarts_to_go = m_jpeg_restart_interval;
00872
00873 return JPEG_OK;
00874 }
00875
00876
00877 JERRCODE CJPEGEncoder::WriteSOS(void)
00878 {
00879 int len;
00880
00881 TRC0("-> WriteSOS");
00882
00883 len = 3 + m_jpeg_ncomp*2 + 3;
00884
00885 if(m_dst.currPos + len >= m_dst.DataLen)
00886 {
00887 LOG0("Error: buffer too small");
00888 return JPEG_BUFF_TOO_SMALL;
00889 }
00890
00891 TRC1(" emit marker ",JM_SOS);
00892 TRC1(" length ",len);
00893
00894 m_dst._WRITE_WORD(0xff00 | JM_SOS);
00895 m_dst._WRITE_WORD(len);
00896
00897 m_dst._WRITE_BYTE(m_jpeg_ncomp);
00898
00899 TRC1(" ncomp ",m_jpeg_ncomp);
00900
00901 for(int i = 0; i < m_jpeg_ncomp; i++)
00902 {
00903 m_dst._WRITE_BYTE(i);
00904 m_dst._WRITE_BYTE((m_ccomp[i]->m_dc_selector << 4) | m_ccomp[i]->m_ac_selector);
00905
00906 TRC1(" id ",i);
00907 TRC1(" dc_selector ",m_ccomp[i]->m_dc_selector);
00908 TRC1(" ac_selector ",m_ccomp[i]->m_ac_selector);
00909 }
00910
00911 m_dst._WRITE_BYTE(m_ss);
00912 m_dst._WRITE_BYTE(m_se);
00913 m_dst._WRITE_BYTE(((m_ah << 4) | m_al));
00914
00915 TRC1(" Ss ",m_ss);
00916 TRC1(" Se ",m_se);
00917 TRC1(" Ah ",m_ah);
00918 TRC1(" Al ",m_al);
00919
00920 return JPEG_OK;
00921 }
00922
00923
00924 JERRCODE CJPEGEncoder::WriteSOS(
00925 int ncomp,
00926 int id[MAX_COMPS_PER_SCAN],
00927 int Ss,
00928 int Se,
00929 int Ah,
00930 int Al)
00931 {
00932 int len;
00933
00934 TRC0("-> WriteSOS");
00935
00936 len = 3 + ncomp*2 + 3;
00937
00938 if(m_dst.currPos + len >= m_dst.DataLen)
00939 {
00940 LOG0("Error: buffer too small");
00941 return JPEG_BUFF_TOO_SMALL;
00942 }
00943
00944 TRC1(" emit marker ",JM_SOS);
00945 TRC1(" length ",len);
00946
00947 m_dst._WRITE_WORD(0xff00 | JM_SOS);
00948 m_dst._WRITE_WORD(len);
00949
00950 m_dst._WRITE_BYTE(ncomp);
00951
00952 TRC1(" ncomp ",ncomp);
00953
00954 for(int i = 0; i < ncomp; i++)
00955 {
00956 m_dst._WRITE_BYTE(id[i]);
00957 m_dst._WRITE_BYTE((m_ccomp[id[i]]->m_dc_selector << 4) | m_ccomp[id[i]]->m_ac_selector);
00958
00959 TRC1(" id ",id[i]);
00960 TRC1(" dc_selector ",m_ccomp[id[i]]->m_dc_selector);
00961 TRC1(" ac_selector ",m_ccomp[id[i]]->m_ac_selector);
00962 }
00963
00964 m_dst._WRITE_BYTE(Ss);
00965 m_dst._WRITE_BYTE(Se);
00966 m_dst._WRITE_BYTE(((Ah & 0x0f) << 4) | (Al & 0x0f));
00967
00968 TRC1(" Ss ",Ss);
00969 TRC1(" Se ",Se);
00970 TRC1(" Ah ",Ah);
00971 TRC1(" Al ",Al);
00972
00973 return JPEG_OK;
00974 }
00975
00976
00977 JERRCODE CJPEGEncoder::SelectScanScripts(void)
00978 {
00979 switch(m_jpeg_ncomp)
00980 {
00981 case 1:
00982 m_scan_count = 6;
00983 m_scan_script = new JPEG_SCAN [m_scan_count];
00984
00985
00986 m_scan_script[0].ncomp = 1;
00987 m_scan_script[0].id[0] = 0;
00988 m_scan_script[0].Ss = 0;
00989 m_scan_script[0].Se = 0;
00990 m_scan_script[0].Ah = 0;
00991 m_scan_script[0].Al = 1;
00992
00993 m_scan_script[1].ncomp = 1;
00994 m_scan_script[1].id[0] = 0;
00995 m_scan_script[1].Ss = 1;
00996 m_scan_script[1].Se = 5;
00997 m_scan_script[1].Ah = 0;
00998 m_scan_script[1].Al = 2;
00999
01000 m_scan_script[2].ncomp = 1;
01001 m_scan_script[2].id[0] = 0;
01002 m_scan_script[2].Ss = 6;
01003 m_scan_script[2].Se = 63;
01004 m_scan_script[2].Ah = 0;
01005 m_scan_script[2].Al = 2;
01006
01007 m_scan_script[3].ncomp = 1;
01008 m_scan_script[3].id[0] = 0;
01009 m_scan_script[3].Ss = 1;
01010 m_scan_script[3].Se = 63;
01011 m_scan_script[3].Ah = 2;
01012 m_scan_script[3].Al = 1;
01013
01014 m_scan_script[4].ncomp = 1;
01015 m_scan_script[4].id[0] = 0;
01016 m_scan_script[4].Ss = 0;
01017 m_scan_script[4].Se = 0;
01018 m_scan_script[4].Ah = 1;
01019 m_scan_script[4].Al = 0;
01020
01021 m_scan_script[5].ncomp = 1;
01022 m_scan_script[5].id[0] = 0;
01023 m_scan_script[5].Ss = 1;
01024 m_scan_script[5].Se = 63;
01025 m_scan_script[5].Ah = 1;
01026 m_scan_script[5].Al = 0;
01027 break;
01028
01029 case 3:
01030 m_scan_count = 10;
01031 m_scan_script = new JPEG_SCAN [m_scan_count];
01032
01033
01034 m_scan_script[0].ncomp = 3;
01035 m_scan_script[0].id[0] = 0;
01036 m_scan_script[0].id[1] = 1;
01037 m_scan_script[0].id[2] = 2;
01038 m_scan_script[0].Ss = 0;
01039 m_scan_script[0].Se = 0;
01040 m_scan_script[0].Ah = 0;
01041 m_scan_script[0].Al = 1;
01042
01043 m_scan_script[1].ncomp = 1;
01044 m_scan_script[1].id[0] = 0;
01045 m_scan_script[1].Ss = 1;
01046 m_scan_script[1].Se = 5;
01047 m_scan_script[1].Ah = 0;
01048 m_scan_script[1].Al = 2;
01049
01050 m_scan_script[2].ncomp = 1;
01051 m_scan_script[2].id[0] = 2;
01052 m_scan_script[2].Ss = 1;
01053 m_scan_script[2].Se = 63;
01054 m_scan_script[2].Ah = 0;
01055 m_scan_script[2].Al = 1;
01056
01057 m_scan_script[3].ncomp = 1;
01058 m_scan_script[3].id[0] = 1;
01059 m_scan_script[3].Ss = 1;
01060 m_scan_script[3].Se = 63;
01061 m_scan_script[3].Ah = 0;
01062 m_scan_script[3].Al = 1;
01063
01064 m_scan_script[4].ncomp = 1;
01065 m_scan_script[4].id[0] = 0;
01066 m_scan_script[4].Ss = 6;
01067 m_scan_script[4].Se = 63;
01068 m_scan_script[4].Ah = 0;
01069 m_scan_script[4].Al = 2;
01070
01071 m_scan_script[5].ncomp = 1;
01072 m_scan_script[5].id[0] = 0;
01073 m_scan_script[5].Ss = 1;
01074 m_scan_script[5].Se = 63;
01075 m_scan_script[5].Ah = 2;
01076 m_scan_script[5].Al = 1;
01077
01078 m_scan_script[6].ncomp = 3;
01079 m_scan_script[6].id[0] = 0;
01080 m_scan_script[6].id[1] = 1;
01081 m_scan_script[6].id[2] = 2;
01082 m_scan_script[6].Ss = 0;
01083 m_scan_script[6].Se = 0;
01084 m_scan_script[6].Ah = 1;
01085 m_scan_script[6].Al = 0;
01086
01087 m_scan_script[7].ncomp = 1;
01088 m_scan_script[7].id[0] = 2;
01089 m_scan_script[7].Ss = 1;
01090 m_scan_script[7].Se = 63;
01091 m_scan_script[7].Ah = 1;
01092 m_scan_script[7].Al = 0;
01093
01094 m_scan_script[8].ncomp = 1;
01095 m_scan_script[8].id[0] = 1;
01096 m_scan_script[8].Ss = 1;
01097 m_scan_script[8].Se = 63;
01098 m_scan_script[8].Ah = 1;
01099 m_scan_script[8].Al = 0;
01100
01101 m_scan_script[9].ncomp = 1;
01102 m_scan_script[9].id[0] = 0;
01103 m_scan_script[9].Ss = 1;
01104 m_scan_script[9].Se = 63;
01105 m_scan_script[9].Ah = 1;
01106 m_scan_script[9].Al = 0;
01107 break;
01108
01109 case 4:
01110 m_scan_count = 18;
01111 m_scan_script = new JPEG_SCAN [m_scan_count];
01112
01113
01114 m_scan_script[0].ncomp = 4;
01115 m_scan_script[0].id[0] = 0;
01116 m_scan_script[0].id[1] = 1;
01117 m_scan_script[0].id[2] = 2;
01118 m_scan_script[0].id[3] = 3;
01119 m_scan_script[0].Ss = 0;
01120 m_scan_script[0].Se = 0;
01121 m_scan_script[0].Ah = 0;
01122 m_scan_script[0].Al = 1;
01123
01124 m_scan_script[1].ncomp = 1;
01125 m_scan_script[1].id[0] = 0;
01126 m_scan_script[1].Ss = 1;
01127 m_scan_script[1].Se = 5;
01128 m_scan_script[1].Ah = 0;
01129 m_scan_script[1].Al = 2;
01130
01131 m_scan_script[2].ncomp = 1;
01132 m_scan_script[2].id[0] = 1;
01133 m_scan_script[2].Ss = 1;
01134 m_scan_script[2].Se = 5;
01135 m_scan_script[2].Ah = 0;
01136 m_scan_script[2].Al = 2;
01137
01138 m_scan_script[3].ncomp = 1;
01139 m_scan_script[3].id[0] = 2;
01140 m_scan_script[3].Ss = 1;
01141 m_scan_script[3].Se = 5;
01142 m_scan_script[3].Ah = 0;
01143 m_scan_script[3].Al = 2;
01144
01145 m_scan_script[4].ncomp = 1;
01146 m_scan_script[4].id[0] = 3;
01147 m_scan_script[4].Ss = 1;
01148 m_scan_script[4].Se = 5;
01149 m_scan_script[4].Ah = 0;
01150 m_scan_script[4].Al = 2;
01151
01152 m_scan_script[5].ncomp = 1;
01153 m_scan_script[5].id[0] = 0;
01154 m_scan_script[5].Ss = 6;
01155 m_scan_script[5].Se = 63;
01156 m_scan_script[5].Ah = 0;
01157 m_scan_script[5].Al = 2;
01158
01159 m_scan_script[6].ncomp = 1;
01160 m_scan_script[6].id[0] = 1;
01161 m_scan_script[6].Ss = 6;
01162 m_scan_script[6].Se = 63;
01163 m_scan_script[6].Ah = 0;
01164 m_scan_script[6].Al = 2;
01165
01166 m_scan_script[7].ncomp = 1;
01167 m_scan_script[7].id[0] = 2;
01168 m_scan_script[7].Ss = 6;
01169 m_scan_script[7].Se = 63;
01170 m_scan_script[7].Ah = 0;
01171 m_scan_script[7].Al = 2;
01172
01173 m_scan_script[8].ncomp = 1;
01174 m_scan_script[8].id[0] = 3;
01175 m_scan_script[8].Ss = 6;
01176 m_scan_script[8].Se = 63;
01177 m_scan_script[8].Ah = 0;
01178 m_scan_script[8].Al = 2;
01179
01180 m_scan_script[9].ncomp = 1;
01181 m_scan_script[9].id[0] = 0;
01182 m_scan_script[9].Ss = 1;
01183 m_scan_script[9].Se = 63;
01184 m_scan_script[9].Ah = 2;
01185 m_scan_script[9].Al = 1;
01186
01187 m_scan_script[10].ncomp = 1;
01188 m_scan_script[10].id[0] = 1;
01189 m_scan_script[10].Ss = 1;
01190 m_scan_script[10].Se = 63;
01191 m_scan_script[10].Ah = 2;
01192 m_scan_script[10].Al = 1;
01193
01194 m_scan_script[11].ncomp = 1;
01195 m_scan_script[11].id[0] = 2;
01196 m_scan_script[11].Ss = 1;
01197 m_scan_script[11].Se = 63;
01198 m_scan_script[11].Ah = 2;
01199 m_scan_script[11].Al = 1;
01200
01201 m_scan_script[12].ncomp = 1;
01202 m_scan_script[12].id[0] = 3;
01203 m_scan_script[12].Ss = 1;
01204 m_scan_script[12].Se = 63;
01205 m_scan_script[12].Ah = 2;
01206 m_scan_script[12].Al = 1;
01207
01208 m_scan_script[13].ncomp = 4;
01209 m_scan_script[13].id[0] = 0;
01210 m_scan_script[13].id[1] = 1;
01211 m_scan_script[13].id[2] = 2;
01212 m_scan_script[13].id[3] = 3;
01213 m_scan_script[13].Ss = 0;
01214 m_scan_script[13].Se = 0;
01215 m_scan_script[13].Ah = 1;
01216 m_scan_script[13].Al = 0;
01217
01218 m_scan_script[14].ncomp = 1;
01219 m_scan_script[14].id[0] = 0;
01220 m_scan_script[14].Ss = 1;
01221 m_scan_script[14].Se = 63;
01222 m_scan_script[14].Ah = 1;
01223 m_scan_script[14].Al = 0;
01224
01225 m_scan_script[15].ncomp = 1;
01226 m_scan_script[15].id[0] = 1;
01227 m_scan_script[15].Ss = 1;
01228 m_scan_script[15].Se = 63;
01229 m_scan_script[15].Ah = 1;
01230 m_scan_script[15].Al = 0;
01231
01232 m_scan_script[16].ncomp = 1;
01233 m_scan_script[16].id[0] = 2;
01234 m_scan_script[16].Ss = 1;
01235 m_scan_script[16].Se = 63;
01236 m_scan_script[16].Ah = 1;
01237 m_scan_script[16].Al = 0;
01238
01239 m_scan_script[17].ncomp = 1;
01240 m_scan_script[17].id[0] = 3;
01241 m_scan_script[17].Ss = 1;
01242 m_scan_script[17].Se = 63;
01243 m_scan_script[17].Ah = 1;
01244 m_scan_script[17].Al = 0;
01245 break;
01246
01247 default:
01248 return JPEG_NOT_IMPLEMENTED;
01249 }
01250
01251 return JPEG_OK;
01252 }
01253
01254
01255 JERRCODE CJPEGEncoder::Init(void)
01256 {
01257 JERRCODE jerr;
01258
01259 switch(m_jpeg_color)
01260 {
01261 case JC_GRAY: m_jpeg_ncomp = 1; break;
01262 case JC_RGB: m_jpeg_ncomp = 3; break;
01263 case JC_YCBCR: m_jpeg_ncomp = 3; break;
01264 case JC_CMYK: m_jpeg_ncomp = 4; break;
01265 case JC_YCCK: m_jpeg_ncomp = 4; break;
01266 default:
01267
01268 break;
01269 }
01270
01271 m_xPadding = m_numxMCU * m_mcuWidth - m_src.width;
01272 m_yPadding = m_numyMCU * m_mcuHeight - m_src.height;
01273
01274 m_ccWidth = m_mcuWidth * m_numxMCU;
01275 m_ccHeight = m_mcuHeight;
01276
01277 for(int i = 0; i < m_jpeg_ncomp; i++)
01278 {
01279 int cc_buf_size;
01280 int ss_buf_size;
01281
01282 switch(m_jpeg_mode)
01283 {
01284 case JPEG_BASELINE:
01285 cc_buf_size = m_ccWidth*m_ccHeight;
01286 ss_buf_size = m_ccWidth*m_ccHeight;
01287 break;
01288
01289 case JPEG_PROGRESSIVE:
01290 cc_buf_size = (m_mcuWidth*m_mcuHeight)*(m_numxMCU*m_numyMCU);
01291 ss_buf_size = (m_mcuWidth*m_mcuHeight)*(m_numxMCU*m_numyMCU);
01292 break;
01293
01294 case JPEG_LOSSLESS:
01295 cc_buf_size = m_ccWidth*sizeof(Ipp16s);
01296 ss_buf_size = m_ccWidth*sizeof(Ipp16s);
01297 break;
01298
01299 default:
01300 return JPEG_INTERNAL_ERROR;
01301 }
01302
01303 if(0 != m_ccomp[i])
01304 {
01305 if(0 != m_ccomp[i]->m_cc_buffer)
01306 {
01307 ippFree(m_ccomp[i]->m_cc_buffer);
01308 m_ccomp[i]->m_cc_buffer = 0;
01309 }
01310
01311 if(0 != m_ccomp[i]->m_ss_buffer)
01312 {
01313 ippFree(m_ccomp[i]->m_ss_buffer);
01314 m_ccomp[i]->m_ss_buffer = 0;
01315 }
01316
01317 delete m_ccomp[i];
01318 }
01319
01320 m_ccomp[i] = new CJPEGColorComponent;
01321 if(0 == m_ccomp[i])
01322 {
01323 return JPEG_OUT_OF_MEMORY;
01324 }
01325
01326 m_ccomp[i]->m_id = i;
01327 m_ccomp[i]->m_comp_no = i;
01328 m_ccomp[i]->m_hsampling = (m_jpeg_sampling == JS_444) ? 1 : (i == 0 || i == 3 ? 2 : 1);
01329 m_ccomp[i]->m_vsampling = (m_jpeg_sampling == JS_411) ? (i == 0 || i == 3 ? 2 : 1) : 1;
01330 m_ccomp[i]->m_h_factor = (m_jpeg_sampling == JS_444) ? 1 : (i == 0 || i == 3? 1 : 2);
01331 m_ccomp[i]->m_v_factor = (m_jpeg_sampling == JS_411) ? (i == 0 || i == 3 ? 1 : 2) : 1;
01332 m_ccomp[i]->m_nblocks = m_ccomp[i]->m_hsampling * m_ccomp[i]->m_vsampling;
01333 m_ccomp[i]->m_q_selector = (i == 0 || i == 3) ? 0 : (m_jpeg_color == JC_YCBCR || m_jpeg_color == JC_YCCK ? 1 : 0);
01334 m_ccomp[i]->m_dc_selector = (i == 0 || i == 3) ? 0 : 1;
01335 m_ccomp[i]->m_ac_selector = (i == 0 || i == 3) ? 0 : 1;
01336
01337
01338 m_ccomp[i]->m_cc_buffer = (Ipp8u*)ippMalloc(cc_buf_size);
01339 if(0 == m_ccomp[i]->m_cc_buffer)
01340 {
01341 return JPEG_OUT_OF_MEMORY;
01342 }
01343
01344
01345 m_ccomp[i]->m_ss_buffer = (Ipp8u*)ippMalloc(ss_buf_size);
01346 if(0 == m_ccomp[i]->m_ss_buffer)
01347 {
01348 return JPEG_OUT_OF_MEMORY;
01349 }
01350
01351
01352 m_ccomp[i]->m_top_row = (Ipp8u*)ippMalloc(ss_buf_size);
01353 if(0 == m_ccomp[i]->m_top_row)
01354 {
01355 return JPEG_OUT_OF_MEMORY;
01356 }
01357
01358 m_ccomp[i]->m_curr_row = (Ipp16s*)m_ccomp[i]->m_cc_buffer;
01359 m_ccomp[i]->m_prev_row = (Ipp16s*)m_ccomp[i]->m_ss_buffer;
01360 }
01361
01362 if(JPEG_PROGRESSIVE == m_jpeg_mode)
01363 {
01364 SelectScanScripts();
01365 }
01366
01367 if(JPEG_PROGRESSIVE == m_jpeg_mode)
01368 {
01369 if(0 == m_coefbuf)
01370 {
01371
01372 int sz = m_numxMCU*m_numyMCU*MAX_BYTES_PER_MCU*sizeof(Ipp16s);
01373
01374 m_coefbuf = (Ipp16s*)ippMalloc(sz);
01375 if(0 == m_coefbuf)
01376 {
01377 return JPEG_OUT_OF_MEMORY;
01378 }
01379
01380 ippsZero_8u((Ipp8u*)m_coefbuf,sz);
01381 }
01382 }
01383
01384 if(JPEG_LOSSLESS != m_jpeg_mode)
01385 {
01386
01387
01388 }
01389
01390 m_dctbl[0].Create();
01391 m_dctbl[1].Create();
01392 m_actbl[0].Create();
01393 m_actbl[1].Create();
01394
01395 if(JPEG_LOSSLESS != m_jpeg_mode)
01396 {
01397 jerr = m_qntbl[0].Init(0,m_jpeg_quality,(Ipp8u*)DefaultLuminanceQuant);
01398 if(JPEG_OK != jerr)
01399 {
01400 LOG0("Error: can't init quant table");
01401 return jerr;
01402 }
01403
01404 jerr = m_qntbl[1].Init(1,m_jpeg_quality,(Ipp8u*)DefaultChrominanceQuant);
01405 if(JPEG_OK != jerr)
01406 {
01407 LOG0("Error: can't init quant table");
01408 return jerr;
01409 }
01410 }
01411
01412 jerr = m_dctbl[0].Init(0,0,(Ipp8u*)DefaultLuminanceDCBits,(Ipp8u*)DefaultLuminanceDCValues);
01413 if(JPEG_OK != jerr)
01414 {
01415 LOG0("Error: can't init huffman table");
01416 return jerr;
01417 }
01418
01419 jerr = m_dctbl[1].Init(1,0,(Ipp8u*)DefaultChrominanceDCBits,(Ipp8u*)DefaultChrominanceDCValues);
01420 if(JPEG_OK != jerr)
01421 {
01422 LOG0("Error: can't init huffman table");
01423 return jerr;
01424 }
01425
01426 jerr = m_actbl[0].Init(0,1,(Ipp8u*)DefaultLuminanceACBits,(Ipp8u*)DefaultLuminanceACValues);
01427 if(JPEG_OK != jerr)
01428 {
01429 LOG0("Error: can't init huffman table");
01430 return jerr;
01431 }
01432
01433 jerr = m_actbl[1].Init(1,1,(Ipp8u*)DefaultChrominanceACBits,(Ipp8u*)DefaultChrominanceACValues);
01434 if(JPEG_OK != jerr)
01435 {
01436 LOG0("Error: can't init huffman table");
01437 return jerr;
01438 }
01439
01440 m_state.Create();
01441
01442 return JPEG_OK;
01443 }
01444
01445
01446 JERRCODE CJPEGEncoder::ColorConvert(void)
01447 {
01448 IppStatus status;
01449
01450 IppiSize roi = { m_src.width, m_src.height };
01451
01452 Ipp8u* src = m_src.p.Data8u;
01453
01454 if(m_jpeg_color == JC_UNKNOWN && m_src.color == JC_UNKNOWN)
01455 {
01456 switch(m_jpeg_ncomp)
01457 {
01458 case 1:
01459 {
01460 Ipp8u* dst = m_ccomp[0]->m_cc_buffer;
01461
01462 status = ippiCopy_8u_C1R(src,m_src.lineStep,dst,m_ccWidth,roi);
01463 if(ippStsNoErr != status)
01464 {
01465 LOG1("IPP Error: ippiCopy_8u_C1R() failed - ",status);
01466 return JPEG_INTERNAL_ERROR;
01467 }
01468 }
01469 break;
01470
01471 case 3:
01472 {
01473 Ipp8u* dst[3];
01474 dst[0] = m_ccomp[0]->m_cc_buffer;
01475 dst[1] = m_ccomp[1]->m_cc_buffer;
01476 dst[2] = m_ccomp[2]->m_cc_buffer;
01477
01478 status = ippiCopy_8u_C3P3R(src,m_src.lineStep,dst,m_ccWidth,roi);
01479
01480 if(ippStsNoErr != status)
01481 {
01482 LOG1("IPP Error: ippiCopy_8u_C3P3R() failed - ",status);
01483 return JPEG_INTERNAL_ERROR;
01484 }
01485 }
01486 break;
01487
01488 case 4:
01489 {
01490 Ipp8u* dst[4];
01491 dst[0] = m_ccomp[0]->m_cc_buffer;
01492 dst[1] = m_ccomp[1]->m_cc_buffer;
01493 dst[2] = m_ccomp[2]->m_cc_buffer;
01494 dst[3] = m_ccomp[3]->m_cc_buffer;
01495
01496 status = ippiCopy_8u_C4P4R(src,m_src.lineStep,dst,m_ccWidth,roi);
01497
01498 if(ippStsNoErr != status)
01499 {
01500 LOG1("IPP Error: ippiCopy_8u_C4P4R() failed - ",status);
01501 return JPEG_INTERNAL_ERROR;
01502 }
01503 }
01504 break;
01505
01506 default:
01507 return JPEG_NOT_IMPLEMENTED;
01508 }
01509 }
01510
01511
01512 if(m_src.color == JC_GRAY && m_jpeg_color == JC_GRAY)
01513 {
01514 Ipp8u* dst = m_ccomp[0]->m_cc_buffer;
01515
01516 status = ippiCopy_8u_C1R(src,m_src.lineStep,dst,m_ccWidth,roi);
01517 if(ippStsNoErr != status)
01518 {
01519 LOG1("IPP Error: ippiCopy_8u_C1R() failed - ",status);
01520 return JPEG_INTERNAL_ERROR;
01521 }
01522 }
01523
01524
01525 if(m_src.color == JC_RGB && m_jpeg_color == JC_GRAY)
01526 {
01527 Ipp8u* dst = m_ccomp[0]->m_cc_buffer;
01528
01529 status = ippiRGBToY_JPEG_8u_C3C1R(src,m_src.lineStep,dst,m_ccWidth,roi);
01530 if(ippStsNoErr != status)
01531 {
01532 LOG1("IPP Error: ippiRGBToY_JPEG_8u_C3C1R() failed - ",status);
01533 return JPEG_INTERNAL_ERROR;
01534 }
01535 }
01536
01537
01538 if(m_src.color == JC_RGB && m_jpeg_color == JC_RGB)
01539 {
01540 Ipp8u* dst[3];
01541 dst[0] = m_ccomp[0]->m_cc_buffer;
01542 dst[1] = m_ccomp[1]->m_cc_buffer;
01543 dst[2] = m_ccomp[2]->m_cc_buffer;
01544
01545 status = ippiCopy_8u_C3P3R(src,m_src.lineStep,dst,m_ccWidth,roi);
01546
01547 if(ippStsNoErr != status)
01548 {
01549 LOG1("IPP Error: ippiCopy_8u_C3P3R() failed - ",status);
01550 return JPEG_INTERNAL_ERROR;
01551 }
01552 }
01553
01554
01555 if(m_src.color == JC_RGB && m_jpeg_color == JC_YCBCR)
01556 {
01557 Ipp8u* dst[3];
01558 dst[0] = m_ccomp[0]->m_cc_buffer;
01559 dst[1] = m_ccomp[1]->m_cc_buffer;
01560 dst[2] = m_ccomp[2]->m_cc_buffer;
01561
01562 status = ippiRGBToYCbCr_JPEG_8u_C3P3R(src,m_src.lineStep,dst,m_ccWidth,roi);
01563
01564 if(ippStsNoErr != status)
01565 {
01566 LOG1("IPP Error: ippiRGBToYCbCr_JPEG_8u_C3P3R() failed - ",status);
01567 return JPEG_INTERNAL_ERROR;
01568 }
01569 }
01570
01571
01572 if(m_src.color == JC_BGR && m_jpeg_color == JC_YCBCR)
01573 {
01574 Ipp8u* dst[3];
01575 dst[0] = m_ccomp[0]->m_cc_buffer;
01576 dst[1] = m_ccomp[1]->m_cc_buffer;
01577 dst[2] = m_ccomp[2]->m_cc_buffer;
01578
01579 status = ippiBGRToYCbCr_JPEG_8u_C3P3R(src,m_src.lineStep,dst,m_ccWidth,roi);
01580
01581 if(ippStsNoErr != status)
01582 {
01583 LOG1("IPP Error: ippiBGRToYCbCr_JPEG_8u_C3P3R() failed - ",status);
01584 return JPEG_INTERNAL_ERROR;
01585 }
01586 }
01587
01588
01589 if(m_src.color == JC_CMYK && m_jpeg_color == JC_CMYK)
01590 {
01591 Ipp8u* dst[4];
01592 dst[0] = m_ccomp[0]->m_cc_buffer;
01593 dst[1] = m_ccomp[1]->m_cc_buffer;
01594 dst[2] = m_ccomp[2]->m_cc_buffer;
01595 dst[3] = m_ccomp[3]->m_cc_buffer;
01596
01597 status = ippiCopy_8u_C4P4R(src,m_src.lineStep,dst,m_ccWidth,roi);
01598
01599 if(ippStsNoErr != status)
01600 {
01601 LOG1("IPP Error: ippiCopy_8u_C4P4R() failed - ",status);
01602 return JPEG_INTERNAL_ERROR;
01603 }
01604 }
01605
01606
01607 if(m_src.color == JC_CMYK && m_jpeg_color == JC_YCCK)
01608 {
01609 Ipp8u* dst[4];
01610 dst[0] = m_ccomp[0]->m_cc_buffer;
01611 dst[1] = m_ccomp[1]->m_cc_buffer;
01612 dst[2] = m_ccomp[2]->m_cc_buffer;
01613 dst[3] = m_ccomp[3]->m_cc_buffer;
01614
01615 status = ippiCMYKToYCCK_JPEG_8u_C4P4R(src,m_src.lineStep,dst,m_ccWidth,roi);
01616
01617 if(ippStsNoErr != status)
01618 {
01619 LOG1("IPP Error: ippiCMYKToYCCK_JPEG_8u_C4P4R() failed - ",status);
01620 return JPEG_INTERNAL_ERROR;
01621 }
01622 }
01623
01624 return JPEG_OK;
01625 }
01626
01627
01628 JERRCODE CJPEGEncoder::ColorConvert(int nMCURow)
01629 {
01630 IppStatus status;
01631
01632 if(nMCURow == m_numyMCU - 1)
01633 {
01634 m_ccHeight = m_mcuHeight - m_yPadding;
01635 }
01636
01637 IppiSize roi = { m_src.width, m_ccHeight };
01638
01639 Ipp8u* src = m_src.p.Data8u + nMCURow*m_mcuHeight*m_src.lineStep;
01640
01641 if(m_jpeg_color == JC_UNKNOWN && m_src.color == JC_UNKNOWN)
01642 {
01643 switch(m_jpeg_ncomp)
01644 {
01645 case 1:
01646 {
01647 Ipp8u* dst = m_ccomp[0]->m_cc_buffer;
01648
01649 status = ippiCopy_8u_C1R(src,m_src.lineStep,dst,m_ccWidth,roi);
01650 if(ippStsNoErr != status)
01651 {
01652 LOG1("IPP Error: ippiCopy_8u_C1R() failed - ",status);
01653 return JPEG_INTERNAL_ERROR;
01654 }
01655 }
01656 break;
01657
01658 case 3:
01659 {
01660 Ipp8u* dst[3];
01661 dst[0] = m_ccomp[0]->m_cc_buffer;
01662 dst[1] = m_ccomp[1]->m_cc_buffer;
01663 dst[2] = m_ccomp[2]->m_cc_buffer;
01664
01665 status = ippiCopy_8u_C3P3R(src,m_src.lineStep,dst,m_ccWidth,roi);
01666
01667 if(ippStsNoErr != status)
01668 {
01669 LOG1("IPP Error: ippiCopy_8u_C3P3R() failed - ",status);
01670 return JPEG_INTERNAL_ERROR;
01671 }
01672 }
01673 break;
01674
01675 case 4:
01676 {
01677 Ipp8u* dst[4];
01678 dst[0] = m_ccomp[0]->m_cc_buffer;
01679 dst[1] = m_ccomp[1]->m_cc_buffer;
01680 dst[2] = m_ccomp[2]->m_cc_buffer;
01681 dst[3] = m_ccomp[3]->m_cc_buffer;
01682
01683 status = ippiCopy_8u_C4P4R(src,m_src.lineStep,dst,m_ccWidth,roi);
01684
01685 if(ippStsNoErr != status)
01686 {
01687 LOG1("IPP Error: ippiCopy_8u_C4P4R() failed - ",status);
01688 return JPEG_INTERNAL_ERROR;
01689 }
01690 }
01691 break;
01692
01693 default:
01694 return JPEG_NOT_IMPLEMENTED;
01695 }
01696 }
01697
01698
01699 if(m_src.color == JC_GRAY && m_jpeg_color == JC_GRAY)
01700 {
01701 Ipp8u* dst = m_ccomp[0]->m_cc_buffer;
01702
01703 status = ippiCopy_8u_C1R(src,m_src.lineStep,dst,m_ccWidth,roi);
01704 if(ippStsNoErr != status)
01705 {
01706 LOG1("IPP Error: ippiCopy_8u_C1R() failed - ",status);
01707 return JPEG_INTERNAL_ERROR;
01708 }
01709 }
01710
01711
01712 if(m_src.color == JC_RGB && m_jpeg_color == JC_GRAY)
01713 {
01714 Ipp8u* dst = m_ccomp[0]->m_cc_buffer;
01715
01716 status = ippiRGBToY_JPEG_8u_C3C1R(src,m_src.lineStep,dst,m_ccWidth,roi);
01717 if(ippStsNoErr != status)
01718 {
01719 LOG1("IPP Error: ippiRGBToY_JPEG_8u_C3C1R() failed - ",status);
01720 return JPEG_INTERNAL_ERROR;
01721 }
01722 }
01723
01724
01725 if(m_src.color == JC_RGB && m_jpeg_color == JC_RGB)
01726 {
01727 Ipp8u* dst[3];
01728 dst[0] = m_ccomp[0]->m_cc_buffer;
01729 dst[1] = m_ccomp[1]->m_cc_buffer;
01730 dst[2] = m_ccomp[2]->m_cc_buffer;
01731
01732 status = ippiCopy_8u_C3P3R(src,m_src.lineStep,dst,m_ccWidth,roi);
01733
01734 if(ippStsNoErr != status)
01735 {
01736 LOG1("IPP Error: ippiCopy_8u_C3P3R() failed - ",status);
01737 return JPEG_INTERNAL_ERROR;
01738 }
01739 }
01740
01741
01742 if(m_src.color == JC_RGB && m_jpeg_color == JC_YCBCR)
01743 {
01744 Ipp8u* dst[3];
01745 dst[0] = m_ccomp[0]->m_cc_buffer;
01746 dst[1] = m_ccomp[1]->m_cc_buffer;
01747 dst[2] = m_ccomp[2]->m_cc_buffer;
01748
01749 status = ippiRGBToYCbCr_JPEG_8u_C3P3R(src,m_src.lineStep,dst,m_ccWidth,roi);
01750
01751 if(ippStsNoErr != status)
01752 {
01753 LOG1("IPP Error: ippiRGBToYCbCr_JPEG_8u_C3P3R() failed - ",status);
01754 return JPEG_INTERNAL_ERROR;
01755 }
01756 }
01757
01758
01759 if(m_src.color == JC_BGR && m_jpeg_color == JC_YCBCR)
01760 {
01761 Ipp8u* dst[3];
01762 dst[0] = m_ccomp[0]->m_cc_buffer;
01763 dst[1] = m_ccomp[1]->m_cc_buffer;
01764 dst[2] = m_ccomp[2]->m_cc_buffer;
01765
01766 status = ippiBGRToYCbCr_JPEG_8u_C3P3R(src,m_src.lineStep,dst,m_ccWidth,roi);
01767
01768 if(ippStsNoErr != status)
01769 {
01770 LOG1("IPP Error: ippiBGRToYCbCr_JPEG_8u_C3P3R() failed - ",status);
01771 return JPEG_INTERNAL_ERROR;
01772 }
01773 }
01774
01775
01776 if(m_src.color == JC_CMYK && m_jpeg_color == JC_CMYK)
01777 {
01778 Ipp8u* dst[4];
01779 dst[0] = m_ccomp[0]->m_cc_buffer;
01780 dst[1] = m_ccomp[1]->m_cc_buffer;
01781 dst[2] = m_ccomp[2]->m_cc_buffer;
01782 dst[3] = m_ccomp[3]->m_cc_buffer;
01783
01784 status = ippiCopy_8u_C4P4R(src,m_src.lineStep,dst,m_ccWidth,roi);
01785
01786 if(ippStsNoErr != status)
01787 {
01788 LOG1("IPP Error: ippiCopy_8u_C4P4R() failed - ",status);
01789 return JPEG_INTERNAL_ERROR;
01790 }
01791 }
01792
01793
01794 if(m_src.color == JC_CMYK && m_jpeg_color == JC_YCCK)
01795 {
01796 Ipp8u* dst[4];
01797 dst[0] = m_ccomp[0]->m_cc_buffer;
01798 dst[1] = m_ccomp[1]->m_cc_buffer;
01799 dst[2] = m_ccomp[2]->m_cc_buffer;
01800 dst[3] = m_ccomp[3]->m_cc_buffer;
01801
01802 status = ippiCMYKToYCCK_JPEG_8u_C4P4R(src,m_src.lineStep,dst,m_ccWidth,roi);
01803
01804 if(ippStsNoErr != status)
01805 {
01806 LOG1("IPP Error: ippiCMYKToYCCK_JPEG_8u_C4P4R() failed - ",status);
01807 return JPEG_INTERNAL_ERROR;
01808 }
01809 }
01810
01811 return JPEG_OK;
01812 }
01813
01814
01815 JERRCODE CJPEGEncoder::DownSampling(void)
01816 {
01817 int i, j, k;
01818
01819 Ipp8u val;
01820 Ipp8u* p;
01821 Ipp8u* p1;
01822
01823 for(k = 0; k < m_jpeg_ncomp; k++)
01824 {
01825
01826 if(m_xPadding)
01827 {
01828 for(i = 0; i < m_src.height; i++)
01829 {
01830 p = m_ccomp[k]->m_cc_buffer + i*m_mcuWidth*m_numxMCU;
01831 val = p[m_src.width - 1];
01832 for(j = 0; j < m_xPadding; j++)
01833 {
01834 p[m_src.width + j] = val;
01835 }
01836 }
01837 }
01838
01839
01840
01841 if(m_yPadding)
01842 {
01843 p = m_ccomp[k]->m_cc_buffer + (m_src.height-1)*m_mcuWidth*m_numxMCU;
01844
01845 for(i = 0; i < m_yPadding; i++)
01846 {
01847 p1 = m_ccomp[k]->m_cc_buffer + m_src.height*m_mcuWidth*m_numxMCU + i*m_mcuWidth*m_numxMCU;
01848 ippsCopy_8u(p,p1,m_mcuWidth*m_numxMCU);
01849 }
01850 }
01851
01852
01853 if(m_ccomp[k]->m_h_factor == 1 && m_ccomp[k]->m_v_factor == 1)
01854 {
01855 Ipp8u* src = m_ccomp[k]->m_cc_buffer;
01856 Ipp8u* dst = m_ccomp[k]->m_ss_buffer;
01857
01858 ippsCopy_8u(src,dst,m_ccWidth*m_mcuHeight*m_numyMCU);
01859 }
01860
01861 IppStatus status;
01862
01863
01864 if(m_ccomp[k]->m_h_factor == 2 && m_ccomp[k]->m_v_factor == 1)
01865 {
01866 Ipp8u* src = m_ccomp[k]->m_cc_buffer;
01867 Ipp8u* dst = m_ccomp[k]->m_ss_buffer;
01868 IppiSize srcRoi = { m_ccWidth, m_mcuHeight*m_numyMCU };
01869 IppiSize dstRoi = { m_ccWidth>>1, m_mcuHeight*m_numyMCU };
01870
01871 status = ippiSampleDownH2V1_JPEG_8u_C1R(src,m_ccWidth,srcRoi,dst,m_ccWidth,dstRoi);
01872
01873 if(ippStsNoErr != status)
01874 {
01875 LOG1("IPP Error: ippiSampleDownH2V1_JPEG_8u_C1R() failed - ",status);
01876 return JPEG_INTERNAL_ERROR;
01877 }
01878 }
01879
01880
01881 if(m_ccomp[k]->m_h_factor == 2 && m_ccomp[k]->m_v_factor == 2)
01882 {
01883 Ipp8u* src = m_ccomp[k]->m_cc_buffer;
01884 Ipp8u* dst = m_ccomp[k]->m_ss_buffer;
01885 IppiSize srcRoi = { m_ccWidth, m_mcuHeight*m_numyMCU };
01886 IppiSize dstRoi = { m_ccWidth>>1, m_mcuHeight*m_numyMCU>>1 };
01887
01888 status = ippiSampleDownH2V2_JPEG_8u_C1R(src,m_ccWidth,srcRoi,dst,m_ccWidth,dstRoi);
01889
01890 if(ippStsNoErr != status)
01891 {
01892 LOG1("IPP Error: ippiSampleDownH2V2_JPEG_8u_C1R() failed - ",status);
01893 return JPEG_INTERNAL_ERROR;
01894 }
01895 }
01896 }
01897
01898 return JPEG_OK;
01899 }
01900
01901
01902 JERRCODE CJPEGEncoder::DownSampling(int nMCURow)
01903 {
01904 int i, j, k;
01905
01906 Ipp8u val;
01907 Ipp8u* p;
01908 Ipp8u* p1;
01909
01910 for(k = 0; k < m_jpeg_ncomp; k++)
01911 {
01912
01913 if(m_xPadding)
01914 {
01915 for(i = 0; i < m_ccHeight; i++)
01916 {
01917 p = m_ccomp[k]->m_cc_buffer + i*m_ccWidth;
01918 val = p[m_src.width - 1];
01919 for(j = 0; j < m_xPadding; j++)
01920 {
01921 p[m_src.width + j] = val;
01922 }
01923 }
01924 }
01925
01926
01927 if(nMCURow == m_numyMCU - 1)
01928 {
01929 p = m_ccomp[k]->m_cc_buffer + (m_ccHeight-1)*m_ccWidth;
01930
01931 for(i = 0; i < m_yPadding; i++)
01932 {
01933 p1 = m_ccomp[k]->m_cc_buffer + m_ccHeight*m_ccWidth + i*m_ccWidth;
01934 ippsCopy_8u(p,p1,m_ccWidth);
01935 }
01936 }
01937
01938
01939 if(m_ccomp[k]->m_h_factor == 1 && m_ccomp[k]->m_v_factor == 1)
01940 {
01941 Ipp8u* src = m_ccomp[k]->m_cc_buffer;
01942 Ipp8u* dst = m_ccomp[k]->m_ss_buffer;
01943
01944 ippsCopy_8u(src,dst,m_ccWidth*m_mcuHeight);
01945 }
01946
01947 IppStatus status;
01948
01949
01950 if(m_ccomp[k]->m_h_factor == 2 && m_ccomp[k]->m_v_factor == 1)
01951 {
01952 Ipp8u* src = m_ccomp[k]->m_cc_buffer;
01953 Ipp8u* dst = m_ccomp[k]->m_ss_buffer;
01954 IppiSize srcRoi = { m_ccWidth, m_mcuHeight };
01955 IppiSize dstRoi = { m_ccWidth>>1, m_mcuHeight };
01956
01957 ippsZero_8u(dst,m_ccWidth*m_mcuHeight);
01958
01959 status = ippiSampleDownH2V1_JPEG_8u_C1R(src,m_ccWidth,srcRoi,dst,m_ccWidth,dstRoi);
01960
01961 if(ippStsNoErr != status)
01962 {
01963 LOG1("IPP Error: ippiSampleDownH2V1_JPEG_8u_C1R() failed - ",status);
01964 return JPEG_INTERNAL_ERROR;
01965 }
01966 }
01967
01968
01969 if(m_ccomp[k]->m_h_factor == 2 && m_ccomp[k]->m_v_factor == 2)
01970 {
01971 Ipp8u* src = m_ccomp[k]->m_cc_buffer;
01972 Ipp8u* dst = m_ccomp[k]->m_ss_buffer;
01973 IppiSize srcRoi = { m_ccWidth, m_mcuHeight };
01974 IppiSize dstRoi = { m_ccWidth>>1, m_mcuHeight>>1 };
01975
01976 status = ippiSampleDownH2V2_JPEG_8u_C1R(src,m_ccWidth,srcRoi,dst,m_ccWidth,dstRoi);
01977
01978 if(ippStsNoErr != status)
01979 {
01980 LOG1("IPP Error: ippiSampleDownH2V2_JPEG_8u_C1R() failed - ",status);
01981 return JPEG_INTERNAL_ERROR;
01982 }
01983 }
01984 }
01985
01986 return JPEG_OK;
01987 }
01988
01989
01990 JERRCODE CJPEGEncoder::PerformDCT(void)
01991 {
01992 int i;
01993 int j;
01994 int n;
01995 int k;
01996 int l;
01997 int size;
01998 int src_step;
01999 Ipp8u* src;
02000 Ipp16u* qtbl;
02001 Ipp16s* block;
02002 IppStatus status;
02003
02004 src_step = m_mcuWidth*m_numxMCU;
02005
02006 for(size = 0, n = 0; n < m_jpeg_ncomp; n++)
02007 {
02008 size += (m_ccomp[n]->m_hsampling * m_ccomp[n]->m_vsampling);
02009 }
02010
02011
02012 for(i = 0; i < m_numyMCU; i++)
02013 {
02014 for(j = 0; j < m_numxMCU; j++)
02015 {
02016 block = m_coefbuf + (DCTSIZE2*size*(j+(i*m_numxMCU)));
02017 for(n = 0; n < m_jpeg_ncomp; n++)
02018 {
02019 for(k = 0; k < m_ccomp[n]->m_vsampling; k++)
02020 {
02021 for(l = 0; l < m_ccomp[n]->m_hsampling; l++)
02022 {
02023 qtbl = m_qntbl[m_ccomp[n]->m_q_selector];
02024
02025 src = m_ccomp[n]->m_ss_buffer +
02026 i*8*m_ccomp[n]->m_vsampling*m_ccWidth +
02027 j*8*m_ccomp[n]->m_hsampling +
02028 k*8*m_ccWidth;
02029
02030 src += l*8;
02031
02032 status = ippiDCTQuantFwd8x8LS_JPEG_8u16s_C1R(
02033 src,
02034 src_step,
02035 block,
02036 qtbl);
02037
02038 if(ippStsNoErr != status)
02039 {
02040 LOG0("Error: ippiDCTQuantFwd8x8LS_JPEG_8u16s_C1R() failed!");
02041 return JPEG_INTERNAL_ERROR;
02042 }
02043
02044 block += DCTSIZE2;
02045 }
02046 }
02047 }
02048 }
02049 }
02050
02051 return JPEG_OK;
02052 }
02053
02054
02055 JERRCODE CJPEGEncoder::GenerateHuffmanTables(
02056 int ncomp,
02057 int id[MAX_COMPS_PER_SCAN],
02058 int Ss,
02059 int Se,
02060 int Ah,
02061 int Al)
02062 {
02063 int i;
02064 int j;
02065 int k;
02066 int n;
02067 int l;
02068 int c;
02069 int size;
02070 int dc_statistics[2][256];
02071 int ac_statistics[2][256];
02072 JERRCODE jerr;
02073 IppStatus status;
02074
02075 ippsZero_8u((Ipp8u*)dc_statistics,sizeof(dc_statistics));
02076 ippsZero_8u((Ipp8u*)ac_statistics,sizeof(ac_statistics));
02077
02078 for(n = 0; n < m_jpeg_ncomp; n++)
02079 {
02080 m_ccomp[n]->m_lastDC = 0;
02081 }
02082
02083 status = ippiEncodeHuffmanStateInit_JPEG_8u(m_state);
02084 if(ippStsNoErr != status)
02085 {
02086 return JPEG_INTERNAL_ERROR;
02087 }
02088
02089 for(size = 0, k = 0; k < m_jpeg_ncomp; k++)
02090 {
02091 size += (m_ccomp[k]->m_hsampling * m_ccomp[k]->m_vsampling);
02092 }
02093
02094 Ipp16s* block;
02095
02096 if(Ss != 0 && Se != 0)
02097 {
02098
02099 for(i = 0; i < m_numyMCU; i++)
02100 {
02101 for(k = 0; k < m_ccomp[id[0]]->m_vsampling; k++)
02102 {
02103 if(i*m_ccomp[id[0]]->m_vsampling*8 + k*8 >= m_src.height)
02104 break;
02105
02106 for(j = 0; j < m_numxMCU; j++)
02107 {
02108 block = m_coefbuf + (DCTSIZE2*size*(j+(i*m_numxMCU)));
02109
02110
02111 for(c = 0; c < m_ccomp[id[0]]->m_comp_no; c++)
02112 {
02113 block += (DCTSIZE2*m_ccomp[c]->m_hsampling*
02114 m_ccomp[c]->m_vsampling);
02115 }
02116
02117
02118 block += (k * DCTSIZE2 * m_ccomp[id[0]]->m_hsampling);
02119
02120 for(l = 0; l < m_ccomp[id[0]]->m_hsampling; l++)
02121 {
02122 if(m_jpeg_restart_interval)
02123 {
02124 if(m_restarts_to_go == 0)
02125 {
02126 jerr = ProcessRestart(ac_statistics,id,Ss,Se,Ah,Al);
02127 if(JPEG_OK != jerr)
02128 {
02129 LOG0("Error: ProcessRestart() failed!");
02130 return jerr;
02131 }
02132 }
02133 }
02134
02135
02136 if(((j*m_ccomp[id[0]]->m_hsampling*8) + (l*8)) >= m_src.width)
02137 break;
02138
02139 if(Ah == 0)
02140 {
02141 status = ippiGetHuffmanStatistics8x8_ACFirst_JPEG_16s_C1(
02142 block,
02143 &ac_statistics[m_ccomp[id[0]]->m_ac_selector][0],
02144 Ss,
02145 Se,
02146 Al,
02147 m_state,
02148 0);
02149
02150 if(ippStsNoErr > status)
02151 {
02152 LOG0("Error: ippiGetHuffmanStatistics8x8_ACFirst_JPEG_16s_C1() failed!");
02153 return JPEG_INTERNAL_ERROR;
02154 }
02155 }
02156 else
02157 {
02158 status = ippiGetHuffmanStatistics8x8_ACRefine_JPEG_16s_C1(
02159 block,
02160 &ac_statistics[m_ccomp[id[0]]->m_ac_selector][0],
02161 Ss,
02162 Se,
02163 Al,
02164 m_state,
02165 0);
02166
02167 if(ippStsNoErr > status)
02168 {
02169 LOG0("Error: ippiGetHuffmanStatistics8x8_ACRefine_JPEG_16s_C1() failed!");
02170 return JPEG_INTERNAL_ERROR;
02171 }
02172 }
02173
02174 block += DCTSIZE2;
02175 m_restarts_to_go --;
02176 }
02177 }
02178 }
02179 }
02180
02181 if(Ah == 0)
02182 {
02183 status = ippiGetHuffmanStatistics8x8_ACFirst_JPEG_16s_C1(
02184 0,
02185 ac_statistics[m_ccomp[id[0]]->m_ac_selector],
02186 Ss,
02187 Se,
02188 Al,
02189 m_state,
02190 1);
02191
02192 if(ippStsNoErr > status)
02193 {
02194 LOG0("Error: ippiGetHuffmanStatistics8x8_ACFirst_JPEG_16s_C1() failed!");
02195 return JPEG_INTERNAL_ERROR;
02196 }
02197 }
02198 else
02199 {
02200 status = ippiGetHuffmanStatistics8x8_ACRefine_JPEG_16s_C1(
02201 0,
02202 ac_statistics[m_ccomp[id[0]]->m_ac_selector],
02203 Ss,
02204 Se,
02205 Al,
02206 m_state,
02207 1);
02208
02209 if(ippStsNoErr > status)
02210 {
02211 LOG0("Error: ippiGetHuffmanStatistics8x8_ACRefine_JPEG_16s_C1() failed!");
02212 return JPEG_INTERNAL_ERROR;
02213 }
02214 }
02215
02216 Ipp8u bits[16];
02217 Ipp8u vals[256];
02218
02219 ippsZero_8u(bits,sizeof(bits));
02220 ippsZero_8u(vals,sizeof(vals));
02221
02222 status = ippiEncodeHuffmanRawTableInit_JPEG_8u(
02223 &ac_statistics[m_ccomp[id[0]]->m_ac_selector][0],
02224 bits,
02225 vals);
02226
02227 if(ippStsNoErr > status)
02228 {
02229 LOG0("Error: ippiEncodeHuffmanRawTableInit_JPEG_8u() failed!");
02230 return JPEG_INTERNAL_ERROR;
02231 }
02232
02233 jerr = m_actbl[m_ccomp[id[0]]->m_ac_selector].Init(m_ccomp[id[0]]->m_ac_selector,1,bits,vals);
02234 if(JPEG_OK != jerr)
02235 {
02236 LOG0("Error: can't init huffman table");
02237 return jerr;
02238 }
02239 }
02240 else
02241 {
02242
02243 if(Ah == 0)
02244 {
02245 for(i = 0; i < m_numyMCU; i++)
02246 {
02247 for(j = 0; j < m_numxMCU; j++)
02248 {
02249 if(m_jpeg_restart_interval)
02250 {
02251 if(m_restarts_to_go == 0)
02252 {
02253 jerr = ProcessRestart(dc_statistics,id,Ss,Se,Ah,Al);
02254 if(JPEG_OK != jerr)
02255 {
02256 LOG0("Error: ProcessRestart() failed!");
02257 return jerr;
02258 }
02259 }
02260 }
02261
02262 block = m_coefbuf + (DCTSIZE2*size*(j+(i*m_numxMCU)));
02263
02264
02265 for(n = 0; n < m_jpeg_ncomp; n++)
02266 {
02267 Ipp16s* lastDC = &m_ccomp[n]->m_lastDC;
02268
02269 for(k = 0; k < m_ccomp[n]->m_vsampling; k++)
02270 {
02271 for(l = 0; l < m_ccomp[n]->m_hsampling; l++)
02272 {
02273 status = ippiGetHuffmanStatistics8x8_DCFirst_JPEG_16s_C1(
02274 block,
02275 dc_statistics[m_ccomp[n]->m_dc_selector],
02276 lastDC,
02277 Al);
02278
02279 if(ippStsNoErr > status)
02280 {
02281 LOG0("Error: ippiGetHuffmanStatistics8x8_DCFirst_JPEG_16s_C1() failed!");
02282 return JPEG_INTERNAL_ERROR;
02283 }
02284
02285 block += DCTSIZE2;
02286 }
02287 }
02288 }
02289 m_restarts_to_go --;
02290 }
02291 }
02292
02293 for(n = 0; n < ncomp; n++)
02294 {
02295 Ipp8u bits[16];
02296 Ipp8u vals[256];
02297
02298 ippsZero_8u(bits,sizeof(bits));
02299 ippsZero_8u(vals,sizeof(vals));
02300
02301 status = ippiEncodeHuffmanRawTableInit_JPEG_8u(
02302 dc_statistics[m_ccomp[n]->m_dc_selector],
02303 bits,
02304 vals);
02305
02306 if(ippStsNoErr > status)
02307 {
02308 LOG0("Error: ippiEncodeHuffmanRawTableInit_JPEG_8u() failed!");
02309 return JPEG_INTERNAL_ERROR;
02310 }
02311
02312 jerr = m_dctbl[m_ccomp[n]->m_dc_selector].Init(m_ccomp[n]->m_dc_selector,0,bits,vals);
02313 if(JPEG_OK != jerr)
02314 {
02315 LOG0("Error: can't init huffman table");
02316 return jerr;
02317 }
02318 }
02319 }
02320 }
02321
02322 return JPEG_OK;
02323 }
02324
02325
02326 JERRCODE CJPEGEncoder::EncodeScan(
02327 int ncomp,
02328 int id[MAX_COMPS_PER_SCAN],
02329 int Ss,
02330 int Se,
02331 int Ah,
02332 int Al)
02333 {
02334 int i;
02335 int j;
02336 int k;
02337 int n;
02338 int l;
02339 int c;
02340 int size;
02341 Ipp16s* block;
02342 JERRCODE jerr;
02343 IppStatus status;
02344
02345 GenerateHuffmanTables(ncomp,id,Ss,Se,Ah,Al);
02346
02347 for(n = 0; n < m_jpeg_ncomp; n++)
02348 {
02349 m_ccomp[n]->m_lastDC = 0;
02350 }
02351
02352 m_restarts_to_go = m_jpeg_restart_interval;
02353
02354 status = ippiEncodeHuffmanStateInit_JPEG_8u(m_state);
02355 if(ippStsNoErr != status)
02356 {
02357 return JPEG_INTERNAL_ERROR;
02358 }
02359
02360 for(size = 0, k = 0; k < m_jpeg_ncomp; k++)
02361 {
02362 size += (m_ccomp[k]->m_hsampling * m_ccomp[k]->m_vsampling);
02363 }
02364
02365 if(Ss != 0 && Se != 0)
02366 {
02367 jerr = WriteDHT(&m_actbl[m_ccomp[id[0]]->m_ac_selector]);
02368 if(JPEG_OK != jerr)
02369 {
02370 LOG0("Error: WriteDHT() failed");
02371 return jerr;
02372 }
02373
02374 jerr = WriteSOS(ncomp,id,Ss,Se,Ah,Al);
02375 if(JPEG_OK != jerr)
02376 {
02377 LOG0("Error: WriteSOS() failed");
02378 return jerr;
02379 }
02380
02381
02382 for(i = 0; i < m_numyMCU; i++)
02383 {
02384 for(k = 0; k < m_ccomp[id[0]]->m_vsampling; k++)
02385 {
02386 if(i*m_ccomp[id[0]]->m_vsampling*8 + k*8 >= m_src.height)
02387 break;
02388
02389 for(j = 0; j < m_numxMCU; j++)
02390 {
02391 block = m_coefbuf + (DCTSIZE2*size*(j+(i*m_numxMCU)));
02392
02393
02394 for(c = 0; c < m_ccomp[id[0]]->m_comp_no; c++)
02395 {
02396 block += (DCTSIZE2*m_ccomp[c]->m_hsampling*
02397 m_ccomp[c]->m_vsampling);
02398 }
02399
02400
02401 block += (k * DCTSIZE2 * m_ccomp[id[0]]->m_hsampling);
02402
02403 for(l = 0; l < m_ccomp[id[0]]->m_hsampling; l++)
02404 {
02405
02406 if(((j*m_ccomp[id[0]]->m_hsampling*8) + (l*8)) >= m_src.width)
02407 break;
02408
02409 if(m_jpeg_restart_interval)
02410 {
02411 if(m_restarts_to_go == 0)
02412 {
02413 jerr = ProcessRestart(id,Ss,Se,Ah,Al);
02414 if(JPEG_OK != jerr)
02415 {
02416 LOG0("Error: ProcessRestart() failed!");
02417 return jerr;
02418 }
02419 }
02420 }
02421
02422 IppiEncodeHuffmanSpec* actbl = m_actbl[m_ccomp[id[0]]->m_ac_selector];
02423
02424 if(Ah == 0)
02425 {
02426 status = ippiEncodeHuffman8x8_ACFirst_JPEG_16s1u_C1(
02427 block,
02428 m_dst.pData,
02429 m_dst.DataLen,
02430 &m_dst.currPos,
02431 Ss,
02432 Se,
02433 Al,
02434 actbl,
02435 m_state,
02436 0);
02437
02438 if(ippStsNoErr > status)
02439 {
02440 LOG1("Error: ippiEncodeHuffman8x8_ACFirst_JPEG_16s1u_C1() failed!",ippGetStatusString(status));
02441 return JPEG_INTERNAL_ERROR;
02442 }
02443 }
02444 else
02445 {
02446 status = ippiEncodeHuffman8x8_ACRefine_JPEG_16s1u_C1(
02447 block,
02448 m_dst.pData,
02449 m_dst.DataLen,
02450 &m_dst.currPos,
02451 Ss,
02452 Se,
02453 Al,
02454 actbl,
02455 m_state,
02456 0);
02457
02458 if(ippStsNoErr > status)
02459 {
02460 LOG1("Error: ippiEncodeHuffman8x8_ACRefine_JPEG_16s1u_C1() failed!",ippGetStatusString(status));
02461 return JPEG_INTERNAL_ERROR;
02462 }
02463 }
02464
02465 block += DCTSIZE2;
02466
02467 m_restarts_to_go --;
02468 }
02469 }
02470 }
02471 }
02472
02473 IppiEncodeHuffmanSpec* actbl = m_actbl[m_ccomp[id[0]]->m_ac_selector];
02474
02475 if(Ah == 0)
02476 {
02477 status = ippiEncodeHuffman8x8_ACFirst_JPEG_16s1u_C1(
02478 0,
02479 m_dst.pData,
02480 m_dst.DataLen,
02481 &m_dst.currPos,
02482 Ss,
02483 Se,
02484 Al,
02485 actbl,
02486 m_state,
02487 1);
02488
02489 if(ippStsNoErr > status)
02490 {
02491 LOG0("Error: ippiEncodeHuffman8x8_ACFirst_JPEG_16s1u_C1() failed!");
02492 return JPEG_INTERNAL_ERROR;
02493 }
02494 }
02495 else
02496 {
02497 status = ippiEncodeHuffman8x8_ACRefine_JPEG_16s1u_C1(
02498 0,
02499 m_dst.pData,
02500 m_dst.DataLen,
02501 &m_dst.currPos,
02502 Ss,
02503 Se,
02504 Al,
02505 actbl,
02506 m_state,
02507 1);
02508
02509 if(ippStsNoErr > status)
02510 {
02511 LOG0("Error: ippiEncodeHuffman8x8_ACRefine_JPEG_16s1u_C1() failed!");
02512 return JPEG_INTERNAL_ERROR;
02513 }
02514 }
02515 }
02516 else
02517 {
02518 if(Ah == 0)
02519 {
02520 jerr = WriteDHT(&m_dctbl[0]);
02521 if(JPEG_OK != jerr)
02522 {
02523 LOG0("Error: WriteDHT() failed");
02524 return jerr;
02525 }
02526
02527 if(m_jpeg_ncomp != 1)
02528 {
02529 jerr = WriteDHT(&m_dctbl[1]);
02530 if(JPEG_OK != jerr)
02531 {
02532 LOG0("Error: WriteDHT() failed");
02533 return jerr;
02534 }
02535 }
02536 }
02537
02538 jerr = WriteSOS(ncomp,id,Ss,Se,Ah,Al);
02539 if(JPEG_OK != jerr)
02540 {
02541 LOG0("Error: WriteSOS() failed");
02542 return jerr;
02543 }
02544
02545
02546 for(i = 0; i < m_numyMCU; i++)
02547 {
02548 for(j = 0; j < m_numxMCU; j++)
02549 {
02550 if(m_jpeg_restart_interval)
02551 {
02552 if(m_restarts_to_go == 0)
02553 {
02554 jerr = ProcessRestart(id,Ss,Se,Ah,Al);
02555 if(JPEG_OK != jerr)
02556 {
02557 LOG0("Error: ProcessRestart() failed!");
02558 return jerr;
02559 }
02560 }
02561 }
02562
02563 block = m_coefbuf + (DCTSIZE2*size*(j+(i*m_numxMCU)));
02564
02565 if(Ah == 0)
02566 {
02567
02568 for(n = 0; n < m_jpeg_ncomp; n++)
02569 {
02570 Ipp16s* lastDC = &m_ccomp[n]->m_lastDC;
02571 IppiEncodeHuffmanSpec* dctbl = m_dctbl[m_ccomp[n]->m_dc_selector];
02572
02573 for(k = 0; k < m_ccomp[n]->m_vsampling; k++)
02574 {
02575 for(l = 0; l < m_ccomp[n]->m_hsampling; l++)
02576 {
02577 status = ippiEncodeHuffman8x8_DCFirst_JPEG_16s1u_C1(
02578 block,
02579 m_dst.pData,
02580 m_dst.DataLen,
02581 &m_dst.currPos,
02582 lastDC,
02583 Al,
02584 dctbl,
02585 m_state,
02586 0);
02587
02588 if(ippStsNoErr > status)
02589 {
02590 LOG1("Error: ippiEncodeHuffman8x8_DCFirst_JPEG_16s1u_C1() failed!",ippGetStatusString(status));
02591 return JPEG_INTERNAL_ERROR;
02592 }
02593
02594 block += DCTSIZE2;
02595 }
02596 }
02597 }
02598 }
02599 else
02600 {
02601
02602 for(n = 0; n < m_jpeg_ncomp; n++)
02603 {
02604 for(k = 0; k < m_ccomp[n]->m_vsampling; k++)
02605 {
02606 for(l = 0; l < m_ccomp[n]->m_hsampling; l++)
02607 {
02608 status = ippiEncodeHuffman8x8_DCRefine_JPEG_16s1u_C1(
02609 block,
02610 m_dst.pData,
02611 m_dst.DataLen,
02612 &m_dst.currPos,
02613 Al,
02614 m_state,
02615 0);
02616
02617 if(ippStsNoErr > status)
02618 {
02619 LOG0("Error: ippiEncodeHuffman8x8_DCRefine_JPEG_16s1u_C1() failed!");
02620 return JPEG_INTERNAL_ERROR;
02621 }
02622
02623 block += DCTSIZE2;
02624 }
02625 }
02626 }
02627 }
02628 m_restarts_to_go --;
02629 }
02630 }
02631
02632 if(Ah == 0)
02633 {
02634 status = ippiEncodeHuffman8x8_DCFirst_JPEG_16s1u_C1(
02635 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,0,0,0,m_state,1);
02636
02637 if(ippStsNoErr > status)
02638 {
02639 LOG0("Error: ippiEncodeHuffman8x8_DCFirst_JPEG_16s1u_C1() failed!");
02640 return JPEG_INTERNAL_ERROR;
02641 }
02642 }
02643 else
02644 {
02645 status = ippiEncodeHuffman8x8_DCRefine_JPEG_16s1u_C1(
02646 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,0,m_state,1);
02647
02648 if(ippStsNoErr > status)
02649 {
02650 LOG0("Error: ippiEncodeHuffman8x8_DCRefine_JPEG_16s1u_C1() failed!");
02651 return JPEG_INTERNAL_ERROR;
02652 }
02653 }
02654 }
02655
02656 return JPEG_OK;
02657 }
02658
02659
02660 JERRCODE CJPEGEncoder::WriteImageBaseline(void)
02661 {
02662 JERRCODE jerr;
02663
02664 jerr = Init();
02665 if(JPEG_OK != jerr)
02666 {
02667 LOG0("Error: can't init encoder");
02668 return jerr;
02669 }
02670
02671 jerr = WriteSOI();
02672 if(JPEG_OK != jerr)
02673 {
02674 LOG0("Error: WriteSOI() failed");
02675 return jerr;
02676 }
02677
02678 if(m_jpeg_color == JC_GRAY || m_jpeg_color == JC_YCBCR)
02679 {
02680 jerr = WriteAPP0();
02681 if(JPEG_OK != jerr)
02682 {
02683 LOG0("Error: WriteAPP0() failed");
02684 return jerr;
02685 }
02686 }
02687
02688 if(m_jpeg_color == JC_RGB || m_jpeg_color == JC_CMYK || m_jpeg_color == JC_YCCK)
02689 {
02690 jerr = WriteAPP14();
02691 if(JPEG_OK != jerr)
02692 {
02693 LOG0("Error: WriteAPP14() failed");
02694 return jerr;
02695 }
02696 }
02697
02698 jerr = WriteCOM();
02699 if(JPEG_OK != jerr)
02700 {
02701 LOG0("Error: WriteCOM() failed");
02702 return jerr;
02703 }
02704
02705 jerr = WriteDQT(&m_qntbl[0]);
02706 if(JPEG_OK != jerr)
02707 {
02708 LOG0("Error: WriteDQT() failed");
02709 return jerr;
02710 }
02711
02712 if(m_jpeg_ncomp != 1)
02713 {
02714 jerr = WriteDQT(&m_qntbl[1]);
02715 if(JPEG_OK != jerr)
02716 {
02717 LOG0("Error: WriteDQT() failed");
02718 return jerr;
02719 }
02720 }
02721
02722 jerr = WriteSOF0();
02723 if(JPEG_OK != jerr)
02724 {
02725 LOG0("Error: WriteSOF0() failed");
02726 return jerr;
02727 }
02728
02729 jerr = WriteDHT(&m_dctbl[0]);
02730 if(JPEG_OK != jerr)
02731 {
02732 LOG0("Error: WriteDHT() failed");
02733 return jerr;
02734 }
02735
02736 if(m_jpeg_ncomp != 1)
02737 {
02738 jerr = WriteDHT(&m_dctbl[1]);
02739 if(JPEG_OK != jerr)
02740 {
02741 LOG0("Error: WriteDHT() failed");
02742 return jerr;
02743 }
02744 }
02745
02746 jerr = WriteDHT(&m_actbl[0]);
02747 if(JPEG_OK != jerr)
02748 {
02749 LOG0("Error: WriteDHT() failed");
02750 return jerr;
02751 }
02752
02753 if(m_jpeg_ncomp != 1)
02754 {
02755 jerr = WriteDHT(&m_actbl[1]);
02756 if(JPEG_OK != jerr)
02757 {
02758 LOG0("Error: WriteDHT() failed");
02759 return jerr;
02760 }
02761 }
02762
02763 if(m_jpeg_restart_interval)
02764 {
02765 jerr = WriteDRI(m_jpeg_restart_interval);
02766 if(JPEG_OK != jerr)
02767 {
02768 LOG0("Error: WriteDRI() failed");
02769 return jerr;
02770 }
02771 }
02772
02773 jerr = WriteSOS();
02774 if(JPEG_OK != jerr)
02775 {
02776 LOG0("Error: WriteSOS() failed");
02777 return jerr;
02778 }
02779
02780 IppStatus status;
02781 IppiEncodeHuffmanSpec* pDCTbl = 0;
02782 IppiEncodeHuffmanSpec* pACTbl = 0;
02783 Ipp8u tmp[DCTSIZE2*sizeof(Ipp16s)+(CPU_CACHE_LINE-1)];
02784 Ipp16s* block = (Ipp16s*)OWN_ALIGN_PTR(&tmp[0],CPU_CACHE_LINE);
02785
02786 status = ippiEncodeHuffmanStateInit_JPEG_8u(m_state);
02787 if(ippStsNoErr != status)
02788 {
02789 return JPEG_INTERNAL_ERROR;
02790 }
02791
02792 for(int i = 0; i < m_numyMCU; i++)
02793 {
02794 jerr = ColorConvert(i);
02795 if(JPEG_OK != jerr)
02796 {
02797 LOG0("Error: ColorConvert() failed");
02798 return jerr;
02799 }
02800
02801 jerr = DownSampling(i);
02802 if(JPEG_OK != jerr)
02803 {
02804 LOG0("Error: DownSampling() failed");
02805 return jerr;
02806 }
02807
02808 Ipp8u* src = 0;
02809 int src_step = m_ccWidth;
02810
02811 for(int j = 0; j < m_numxMCU; j++)
02812 {
02813
02814 if(m_jpeg_restart_interval)
02815 {
02816 if(m_restarts_to_go == 0)
02817 {
02818 ProcessRestart(0,0,63,0,0);
02819 }
02820 }
02821
02822 for(int n = 0; n < m_jpeg_ncomp; n++)
02823 {
02824 Ipp16u* qtbl = m_qntbl[m_ccomp[n]->m_q_selector];
02825
02826 pDCTbl = m_dctbl[m_ccomp[n]->m_dc_selector];
02827 pACTbl = m_actbl[m_ccomp[n]->m_ac_selector];
02828
02829 for(int k = 0; k < m_ccomp[n]->m_vsampling; k++)
02830 {
02831 src = m_ccomp[n]->m_ss_buffer + j*8*m_ccomp[n]->m_hsampling + k*8*m_ccWidth;
02832
02833 for(int l = 0; l < m_ccomp[n]->m_hsampling; l++)
02834 {
02835 src += l*8;
02836 status = ippiDCTQuantFwd8x8LS_JPEG_8u16s_C1R(
02837 src,
02838 src_step,
02839 block,
02840 qtbl);
02841
02842 if(ippStsNoErr > status)
02843 {
02844 LOG1("IPP Error: ippiDCTQuantFwd8x8LS_JPEG_8u16s_C1R() failed - ",status);
02845 return JPEG_INTERNAL_ERROR;
02846 }
02847
02848 status = ippiEncodeHuffman8x8_JPEG_16s1u_C1(
02849 block,
02850 m_dst.pData,
02851 m_dst.DataLen,
02852 &m_dst.currPos,
02853 &m_ccomp[n]->m_lastDC,
02854 pDCTbl,
02855 pACTbl,
02856 m_state,
02857 0);
02858
02859 if(ippStsNoErr > status)
02860 {
02861 LOG1("IPP Error: ippiEncodeHuffman8x8_JPEG_16s1u_C1() failed - ",status);
02862 return JPEG_INTERNAL_ERROR;
02863 }
02864 }
02865 }
02866 }
02867
02868 if(m_jpeg_restart_interval)
02869 {
02870 if(m_restarts_to_go == 0)
02871 {
02872 m_restarts_to_go = m_jpeg_restart_interval;
02873 }
02874 m_restarts_to_go --;
02875 }
02876 }
02877 }
02878
02879
02880 status = ippiEncodeHuffman8x8_JPEG_16s1u_C1(
02881 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,0,0,0,m_state,1);
02882
02883 if(ippStsNoErr > status)
02884 {
02885 LOG1("IPP Error: ippiEncodeHuffman8x8_JPEG_16s1u_C1() failed - ",status);
02886 return JPEG_INTERNAL_ERROR;
02887 }
02888
02889 jerr = WriteEOI();
02890 if(JPEG_OK != jerr)
02891 {
02892 LOG0("Error: WriteEOI() failed");
02893 return jerr;
02894 }
02895
02896 return JPEG_OK;
02897 }
02898
02899
02900 JERRCODE CJPEGEncoder::WriteImageProgressive(void)
02901 {
02902 int i;
02903 JERRCODE jerr;
02904
02905 jerr = Init();
02906 if(JPEG_OK != jerr)
02907 {
02908 LOG0("Error: can't init encoder");
02909 return jerr;
02910 }
02911
02912 jerr = WriteSOI();
02913 if(JPEG_OK != jerr)
02914 {
02915 LOG0("Error: WriteSOI() failed");
02916 return jerr;
02917 }
02918
02919 if(m_jpeg_color == JC_GRAY || m_jpeg_color == JC_YCBCR)
02920 {
02921 jerr = WriteAPP0();
02922 if(JPEG_OK != jerr)
02923 {
02924 LOG0("Error: WriteAPP0() failed");
02925 return jerr;
02926 }
02927 }
02928
02929 if(m_jpeg_color == JC_RGB || m_jpeg_color == JC_CMYK || m_jpeg_color == JC_YCCK)
02930 {
02931 jerr = WriteAPP14();
02932 if(JPEG_OK != jerr)
02933 {
02934 LOG0("Error: WriteAPP14() failed");
02935 return jerr;
02936 }
02937 }
02938
02939 jerr = WriteCOM();
02940 if(JPEG_OK != jerr)
02941 {
02942 LOG0("Error: WriteCOM() failed");
02943 return jerr;
02944 }
02945
02946 jerr = WriteDQT(&m_qntbl[0]);
02947 if(JPEG_OK != jerr)
02948 {
02949 LOG0("Error: WriteDQT() failed");
02950 return jerr;
02951 }
02952
02953 if(m_jpeg_ncomp != 1 && m_jpeg_color != JC_RGB && m_jpeg_color != JC_CMYK && m_jpeg_color != JC_UNKNOWN)
02954 {
02955 jerr = WriteDQT(&m_qntbl[1]);
02956 if(JPEG_OK != jerr)
02957 {
02958 LOG0("Error: WriteDQT() failed");
02959 return jerr;
02960 }
02961 }
02962
02963 jerr = WriteSOF2();
02964 if(JPEG_OK != jerr)
02965 {
02966 LOG0("Error: WriteSOF2() failed");
02967 return jerr;
02968 }
02969
02970
02971 jerr = ColorConvert();
02972 if(JPEG_OK != jerr)
02973 {
02974 LOG0("Error: ColorConvert() failed");
02975 return jerr;
02976 }
02977
02978 jerr = DownSampling();
02979 if(JPEG_OK != jerr)
02980 {
02981 LOG0("Error: DownSampling() failed");
02982 return jerr;
02983 }
02984
02985 jerr = PerformDCT();
02986 if(JPEG_OK != jerr)
02987 {
02988 LOG0("Error: PerformDCT() failed");
02989 return jerr;
02990 }
02991
02992 if(m_jpeg_restart_interval)
02993 {
02994 jerr = WriteDRI(m_jpeg_restart_interval);
02995 if(JPEG_OK != jerr)
02996 {
02997 LOG0("Error: WriteDRI() failed");
02998 return jerr;
02999 }
03000 }
03001
03002 for(i = 0; i < m_scan_count; i++)
03003 {
03004 m_next_restart_num = 0;
03005 m_restarts_to_go = m_jpeg_restart_interval;
03006
03007 jerr = EncodeScan(
03008 m_scan_script[i].ncomp,
03009 m_scan_script[i].id,
03010 m_scan_script[i].Ss,
03011 m_scan_script[i].Se,
03012 m_scan_script[i].Ah,
03013 m_scan_script[i].Al);
03014 if(JPEG_OK != jerr)
03015 {
03016 LOG0("Error: EncodeScan() failed");
03017 return jerr;
03018 }
03019 }
03020
03021 jerr = WriteEOI();
03022 if(JPEG_OK != jerr)
03023 {
03024 LOG0("Error: WriteEOI() failed");
03025 return jerr;
03026 }
03027
03028 return JPEG_OK;
03029 }
03030
03031
03032 JERRCODE CJPEGEncoder::WriteImageLossless(void)
03033 {
03034 int i, j;
03035 JERRCODE jerr;
03036
03037 jerr = Init();
03038 if(JPEG_OK != jerr)
03039 {
03040 LOG0("Error: can't init encoder");
03041 return jerr;
03042 }
03043
03044 if(m_jpeg_ncomp != 1)
03045 {
03046 return JPEG_NOT_IMPLEMENTED;
03047 }
03048
03049 m_ss = m_predictor;
03050 m_se = 0;
03051 m_ah = 0;
03052 m_al = m_pt;
03053
03054 jerr = WriteSOI();
03055 if(JPEG_OK != jerr)
03056 {
03057 LOG0("Error: WriteSOI() failed");
03058 return jerr;
03059 }
03060
03061 if(m_jpeg_color == JC_GRAY)
03062 {
03063 jerr = WriteAPP0();
03064 if(JPEG_OK != jerr)
03065 {
03066 LOG0("Error: WriteAPP0() failed");
03067 return jerr;
03068 }
03069 }
03070
03071 jerr = WriteCOM();
03072 if(JPEG_OK != jerr)
03073 {
03074 LOG0("Error: WriteCOM() failed");
03075 return jerr;
03076 }
03077
03078 jerr = WriteSOF3();
03079 if(JPEG_OK != jerr)
03080 {
03081 LOG0("Error: WriteSOF3() failed");
03082 return jerr;
03083 }
03084
03085 jerr = WriteDHT(&m_dctbl[0]);
03086 if(JPEG_OK != jerr)
03087 {
03088 LOG0("Error: WriteDHT() failed");
03089 return jerr;
03090 }
03091
03092 if(m_jpeg_restart_interval)
03093 {
03094 return JPEG_NOT_IMPLEMENTED;
03095 }
03096
03097 jerr = WriteSOS();
03098 if(JPEG_OK != jerr)
03099 {
03100 LOG0("Error: WriteSOS() failed");
03101 return jerr;
03102 }
03103
03104 Ipp8u* pSrc;
03105 Ipp16s* pMCUBuf;
03106 Ipp16s* pCurrRow;
03107 Ipp16s* pPrevRow;
03108 IppiEncodeHuffmanSpec* pDCTbl;
03109 IppiSize roi;
03110 IppStatus status;
03111 int stat[256];
03112 Ipp8u bits[16];
03113 Ipp8u vals[256];
03114
03115 roi.width = m_src.width;
03116 roi.height = 1;
03117
03118 ippsZero_8u((Ipp8u*)stat,256*sizeof(int));
03119 ippsZero_8u(bits,16);
03120 ippsZero_8u(vals,256);
03121
03122 status = ippiEncodeHuffmanStateInit_JPEG_8u(m_state);
03123 if(ippStsNoErr != status)
03124 {
03125 return JPEG_INTERNAL_ERROR;
03126 }
03127
03128 for(i = 0; i < m_numyMCU; i++)
03129 {
03130 pSrc = m_src.p.Data8u + i*m_src.lineStep;
03131 pMCUBuf = (Ipp16s*)m_ccomp[0]->m_top_row;
03132
03133 pCurrRow = m_ccomp[0]->m_curr_row;
03134 pPrevRow = m_ccomp[0]->m_prev_row;
03135
03136 status = ippiConvert_8u16s_C1R(pSrc,m_src.lineStep,pCurrRow,m_numxMCU,roi);
03137 if(ippStsNoErr > status)
03138 {
03139 LOG1("IPP Error: ippiConvert_8u16s_C1R() failed - ",status);
03140 return JPEG_INTERNAL_ERROR;
03141 }
03142
03143 if(m_al)
03144 {
03145
03146 ippsRShiftC_16s_I(m_al,pCurrRow,m_numxMCU);
03147 }
03148
03149 if(i != 0)
03150 {
03151 m_al = 0;
03152 m_ss = 1;
03153 status = ippiDiffPredRow_JPEG_16s_C1(pCurrRow,pPrevRow,pMCUBuf,m_src.width,m_ss);
03154 if(ippStsNoErr > status)
03155 {
03156 LOG1("IPP Error: ippiDiffPredRow_JPEG_16s_C1() failed - ",status);
03157 return JPEG_INTERNAL_ERROR;
03158 }
03159 }
03160 else
03161 {
03162 m_al = 0;
03163 status = ippiDiffPredFirstRow_JPEG_16s_C1(pCurrRow,pMCUBuf,m_src.width,m_jpeg_precision,m_al);
03164 if(ippStsNoErr > status)
03165 {
03166 LOG1("IPP Error: ippiDiffPredFirstRow_JPEG_16s_C1() failed - ",status);
03167 return JPEG_INTERNAL_ERROR;
03168 }
03169 }
03170
03171 m_ccomp[0]->m_curr_row = pPrevRow;
03172 m_ccomp[0]->m_prev_row = pCurrRow;
03173
03174 for(j = 0; j < m_numxMCU; j++)
03175 {
03176 pDCTbl = m_dctbl[m_ccomp[0]->m_dc_selector];
03177
03178 status = ippiEncodeHuffmanOne_JPEG_16s1u_C1(
03179 pMCUBuf,
03180 m_dst.pData,
03181 m_dst.DataLen,
03182 &m_dst.currPos,
03183 pDCTbl,
03184 m_state,
03185 0);
03186
03187 if(ippStsNoErr > status)
03188 {
03189 LOG1("IPP Error: ippiEncodeHuffmanOne_JPEG_16s1u_C1() failed - ",status);
03190 return JPEG_INTERNAL_ERROR;
03191 }
03192
03193 pMCUBuf++;
03194 }
03195 }
03196
03197
03198 status = ippiEncodeHuffmanOne_JPEG_16s1u_C1(
03199 0,m_dst.pData,m_dst.DataLen,&m_dst.currPos,0,m_state,1);
03200
03201 if(ippStsNoErr > status)
03202 {
03203 LOG1("IPP Error: ippiEncodeHuffmanOne_JPEG_16s1u_C1() failed - ",status);
03204 return JPEG_INTERNAL_ERROR;
03205 }
03206
03207 jerr = WriteEOI();
03208 if(JPEG_OK != jerr)
03209 {
03210 LOG0("Error: WriteEOI() failed");
03211 return jerr;
03212 }
03213
03214 return JPEG_OK;
03215 }
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472