decoder.cpp
Go to the documentation of this file.
00001 /*
00002 //
00003 //               INTEL CORPORATION PROPRIETARY INFORMATION
00004 //  This software is supplied under the terms of a license agreement or
00005 //  nondisclosure agreement with Intel Corporation and may not be copied
00006 //  or disclosed except in accordance with the terms of that agreement.
00007 //    Copyright (c) 2001-2004 Intel Corporation. All Rights Reserved.
00008 //
00009 //  Intel® Integrated Performance Primitives JPEG Viewer Sample for Windows*
00010 //
00011 //  By downloading and installing this sample, you hereby agree that the
00012 //  accompanying Materials are being provided to you under the terms and
00013 //  conditions of the End User License Agreement for the Intel® Integrated
00014 //  Performance Primitives product previously accepted by you. Please refer
00015 //  to the file ipplic.htm located in the root directory of your Intel® IPP product
00016 //  installation for more information.
00017 //
00018 //  JPEG is an international standard promoted by ISO/IEC and other organizations.
00019 //  Implementations of these standards, or the standard enabled platforms may
00020 //  require licenses from various entities, including Intel Corporation.
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)//OMP
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)//OMP
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 } // ctor
00076 
00077 
00078 CJPEGDecoder::~CJPEGDecoder(void)
00079 {
00080         //printf("~CJPEGDecoder\n");
00081         Clean();
00082         return;
00083 } // dtor
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; //OMP
00161         m_nblock       = 1;    //OMP
00162 
00163 #ifdef __TIMING__
00164         m_clk_diff = 0;
00165         m_clk_huff = 0;
00166 #endif
00167 
00168         return;
00169 } // CJPEGDecoder::Reset(void)
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 } // CJPEGDecoder::Clean()
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 } // CJPEGDecoder::SetSource()
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 } // CJPEGDecoder::SetDestination()
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 } // CJPEGDecoder::SetDestination()
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 } // CJPEGDecoder::_set_sampling()
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 } // CJPEGDecoder::NextMarker()
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 } // CJPEGDecoder::SkipMarker()
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                 //    return jerr;
00435         }
00436 
00437         m_restarts_to_go = m_jpeg_restart_interval;
00438 
00439         return JPEG_OK;
00440 } // CJPEGDecoder::ProcessRestart()
00441 
00442 
00443 JERRCODE CJPEGDecoder::ParseSOI(void)
00444 {
00445         TRC0("-> SOI");
00446         m_marker = JM_NONE;
00447         return JPEG_OK;
00448 } // CJPEGDecoder::ParseSOI()
00449 
00450 
00451 JERRCODE CJPEGDecoder::ParseEOI(void)
00452 {
00453         TRC0("-> EOI");
00454         m_marker = JM_NONE;
00455         return JPEG_OK;
00456 } // CJPEGDecoder::ParseEOI()
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                 // we've found JFIF APP0 marker
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                 // we've found JFXX APP0 extension marker
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 } // CJPEGDecoder::ParseAPP0()
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                 // we've found Adobe APP14 marker
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 } // CJPEGDecoder::ParseAPP14()
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 } // CJPEGDecoder::ParseCOM()
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 } // CJPEGDecoder::ParseDQT()
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                         // make AC Huffman table
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                         // make DC Huffman table
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 } // CJPEGDecoder::ParseDHT()
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 } // CJPEGDecoder::ParseSOF0()
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 } // CJPEGDecoder::ParseSOF2()
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 } // CJPEGDecoder::ParseSOF3()
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 } // CJPEGDecoder::ParseDRI()
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                 //    return JPEG_BAD_RESTART;
01150         }
01151 
01152         // Update next-restart state
01153         m_next_restart_num = (m_next_restart_num + 1) & 7;
01154 
01155         return JPEG_OK;
01156 } // CJPEGDecoder::ParseRST()
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         // store position to return to in subsequent ReadData call
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                 // does not support scan-interleaved images for now..
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         // detect JPEG color space
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         // try to guess what color space is used...
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 } // CJPEGDecoder::ParseSOS()
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                                         // stop here, when we are reading header
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 } // CJPEGDecoder::ParseJPEGBitStream()
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                 // there is no threading support for 411 sampling yet
01534                 num_threads = 1;
01535                 set_num_threads(num_threads);
01536         }
01537 
01538         // not implemented yet
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                                 } // JPEG_BASELINE
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                                 } // JPEG_PROGRESSIVE
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                                 } // JPEG_LOSSLESS
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         } // m_jpeg_ncomp
01683 
01684         m_state.Create();
01685 
01686         return JPEG_OK;
01687 } // CJPEGDecoder::Init()
01688 
01689 
01690 JERRCODE CJPEGDecoder::ColorConvert(int nMCURow,int idThread)
01691 {
01692         IppStatus status;
01693         int threadoffset = (m_numxMCU*m_mcuWidth)*(idThread*m_mcuHeight);//OMP
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         // Gray to Gray
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         // Gray to RGB
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         // Gray to BGR
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         // RGB to RGB
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         // RGB to BGR
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         // YCbCr to RGB
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         // YCbCr to BGR
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         // CMYK to CMYK
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         // YCCK to CMYK
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 } // CJPEGDecoder::ColorConvert()
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         // Gray to Gray
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         // Gray to RGB
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         // Gray to BGR
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         // RGB to RGB
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         // RGB to BGR
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         // YCbCr to RGB
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         // YCbCr to BGR
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         // CMYK to CMYK
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         // YCCK to CMYK
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 } // CJPEGDecoder::ColorConvert()
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;//OMP
02138         int threadOffsetSS; // OMP
02139         IppStatus status;
02140 
02141         threadOffsetCC = (m_numxMCU*m_mcuWidth)*(idThread*m_mcuHeight);//OMP
02142         threadOffsetSS = 0; // OMP
02143 
02144         if(m_jpeg_sampling == JS_422)
02145                 threadOffsetSS = m_numxMCU*((m_mcuWidth>>1)+2) * idThread * m_mcuHeight;//OMP
02146         else if(m_jpeg_sampling == JS_411)
02147                 threadOffsetSS = m_numxMCU*((m_mcuWidth>>1)+2) * idThread * ((m_mcuHeight>>1)+2);//OMP
02148 
02149         for(k = 0; k < m_jpeg_ncomp; k++)
02150         {
02151                 // sampling 444
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                 // sampling 422
02163                 if(m_ccomp[k]->m_h_factor == 2 && m_ccomp[k]->m_v_factor == 1)
02164                 {
02165                         // pad most left and most right column
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                 // sampling 411
02194                 if(m_ccomp[k]->m_h_factor == 2 && m_ccomp[k]->m_v_factor == 2)
02195                 {
02196                         // pad most left and most right columns
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                 }//411
02248         } // for m_jpeg_ncomp
02249 
02250         return JPEG_OK;
02251 } // CJPEGDecoder::UpSampling()
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                 // sampling 444
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                 // sampling 422
02274                 if(m_ccomp[k]->m_h_factor == 2 && m_ccomp[k]->m_v_factor == 1)
02275                 {
02276                         // pad most left and most right columns
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                 // sampling 411
02303                 if(m_ccomp[k]->m_h_factor == 2 && m_ccomp[k]->m_v_factor == 2)
02304                 {
02305                         // pad most left and most right columns
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                         // replicate top row
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                         // replicate bottom row
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         } // for m_jpeg_ncomp
02341 
02342         return JPEG_OK;
02343 } // CJPEGDecoder::UpSampling()
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                                         } // for m_hsampling
02407                                 } // for m_vsampling
02408                         }
02409                 }
02410         }
02411 
02412         return JPEG_OK;
02413 } // CJPEGDecoder::PerformDCT()
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 } // CJPEGDecoder::ReadHeader()
02463 
02464 
02465 JERRCODE CJPEGDecoder::ReadData(void)
02466 {
02467         return ParseJPEGBitStream(JO_READ_DATA);
02468 } // CJPEGDecoder::ReadData()
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                                 } // for m_hsampling
02526                         } // for m_vsampling
02527                 } // for m_jpeg_ncomp
02528 
02529                 m_restarts_to_go--;
02530         } // for m_numxMCU
02531 
02532         return JPEG_OK;
02533 } // CJPEGDecoder::DecodeHuffmanMCURowBL()
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                                 } // for m_hsampling
02587                         } // for m_vsampling
02588                 } // for m_jpeg_ncomp
02589 
02590                 m_restarts_to_go --;
02591         } // for m_numxMCU
02592 
02593         return JPEG_OK;
02594 } // CJPEGDecoder::DecodeHuffmanMCURowLS()
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; // OMP
02612         else if(m_jpeg_sampling == JS_411)
02613                 threadOffsetSS = m_numxMCU*((m_mcuWidth>>1)+2) * idThread * ((m_mcuHeight>>1)+2); // OMP
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                                 } // for m_hsampling
02668                         } // for m_vsampling
02669                 } // for m_jpeg_ncomp
02670         } // for m_numxMCU
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 } // CJPEGDecoder::DCT_QNT_SSCC_MCURowBL()
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 } // CJPEGDecoder::ReconstructMCURowLS()
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;  // the pointer to Buffer for a current thread.
02766 
02767 #ifdef _OPENMP
02768                 idThread = omp_get_thread_num(); // the thread id of the calling thread.
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                 } // for m_numyMCU
02796         } // OMP
02797 
02798         if(m_jpeg_sampling == JS_411)
02799                 set_num_threads(m_num_threads);
02800 
02801         return JPEG_OK;
02802 } // CJPEGDecoder::DecodeScanBaseline()
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                 // AC scan
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                                         // skip any relevant components
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                                         // Skip over relevant 8x8 blocks from this component.
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                                                 // Ignore the last column(s) of the image.
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                                         } // for m_hsampling
02924                                 } // for m_numxMCU
02925                         } // for m_vsampling
02926                 } // for m_numyMCU
02927                 if(m_al == 0)
02928                 {
02929                         m_ccomp[m_curr_comp_no]->m_ac_scan_completed = 1;
02930                 }
02931         }
02932         else
02933         {
02934                 // DC scan
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                                         // first DC scan
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                                                         } // for m_hsampling
02985                                                 } // for m_vsampling
02986                                         } // for m_jpeg_ncomp
02987                                 }
02988                                 else
02989                                 {
02990                                         // refine DC scan
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                                                         } // for m_hsampling
03014                                                 } // for m_vsampling
03015                                         } // for m_jpeg_ncomp
03016                                 }
03017                                 m_restarts_to_go --;
03018                         } // for m_numxMCU
03019                 } // for m_numyMCU
03020 
03021                 if(m_al == 0)
03022                 {
03023                         m_dc_scan_completed = 1;
03024                 }
03025         }
03026 
03027         return JPEG_OK;
03028 } // CJPEGDecoder::DecodeScanProgressive()
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++; // advance counter to the next mcu row
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         } // for m_numyMCU
03095 
03096         return JPEG_OK;
03097 } // CJPEGDecoder::DecodeScanLossless()
03098 


canon_vbc50i
Author(s): Cedric Pradalier
autogenerated on Mon Jan 6 2014 11:18:27