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