1 // Copyright (c) 2018 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 //  Purpose:
22 //    Huffman entropy encoder
23 //
24 //  Contents:
25 //    mfxiEncodeHuffmanRawTableInit_JPEG_8u,
26 //    mfxiEncodeHuffmanSpecGetBufSize_JPEG_8u,
27 //    mfxiEncodeHuffmanStateGetBufSize_JPEG_8u,
28 //    mfxiEncodeHuffmanStateInit_JPEG_8u,
29 //    mfxiEncodeHuffman8x8_JPEG_16s1u_C1,
30 //    mfxiGetHuffmanStatistics8x8_JPEG_16s_C1
31 //
32 
33 #include "precomp.h"
34 
35 #ifndef __OWNJ_H__
36 #include "ownj.h"
37 #endif
38 #ifndef __PSCOPY_H__
39 #include "pscopy.h"
40 #endif
41 #ifndef __PJZIGZAG_H__
42 #include "pjzigzag.h"
43 #endif
44 #ifndef __PJHUFFTBL_H__
45 #include "pjhufftbl.h"
46 #endif
47 #ifndef __PJENCHUFF_H__
48 #include "pjenchuff.h"
49 #endif
50 
51 
52 
53 #define MAX_CODE_LEN 32
54 
55 LOCFUN(IppStatus,mfxownpj_EncodeHuffmanSpecInit,(
56   const Ipp8u*                  pBits,
57   const Ipp8u*                  pVals,
58         ownpjEncodeHuffmanSpec* pEncHuffTbl))
59 {
60   int i;
61   int j;
62   int k;
63   unsigned int si;
64   unsigned int code;
65   int lastk;
66   unsigned int huffsize[257];
67   unsigned int huffcode[257];
68 
69   mfxownsZero_8u((Ipp8u*)pEncHuffTbl,sizeof(ownpjEncodeHuffmanSpec));
70   mfxownsZero_8u((Ipp8u*)&huffsize[0],sizeof(huffsize));
71   mfxownsZero_8u((Ipp8u*)&huffcode[0],sizeof(huffcode));
72 
73   /* Generate Size Table */
74   /* ISO/IEC 10918-1, Figure C.1 - Generation of table of Huffman code sizes */
75 
76   k = 0;
77 
78   for(i = 0; i < 16; i++)
79   {
80     j = pBits[i];
81 
82     if((k + j) > 256)
83     {
84       /* protect against table overrun */
85       return ippStsJPEGHuffTableErr;
86     }
87 
88     while(j--)
89     {
90       huffsize[k++] = (i + 1);
91     }
92   }
93 
94   huffsize[k] = 0;
95   lastk       = k;
96 
97   /* Generate Code Table */
98   /* ISO/IEC 10918-1, Figure C.2 - Generation of table of Huffman codes */
99 
100   k    = 0;
101   code = 0;
102   si   = huffsize[0];
103 
104   while(huffsize[k])
105   {
106     while(huffsize[k] == si)
107     {
108       huffcode[k++] = code;
109       code++;
110     }
111     /* code is now 1 more than the last code used for codelength si; but
112      * it must still fit in si bits, since no code is allowed to be all ones.
113      */
114     if(code >= (unsigned int)(1 << si))
115     {
116       /* corrupted table */
117       return ippStsJPEGHuffTableErr;
118     }
119     code <<= 1;
120     si++;
121   }
122 
123   /* Order Codes */
124   /* ISO/IEC 10918-1, Figure C.3 - Ordering procedure for encoding */
125   /* procedure code tables */
126 
127   for(k = 0; k < lastk; k++)
128   {
129     i                   = (int)pVals[k];
130     pEncHuffTbl->hcs[i] = (huffsize[k] << 16) | (huffcode[k] & 0xffff);
131   }
132 
133   return ippStsNoErr;
134 } /* mfxownpj_EncodeHuffmanSpecInit() */
135 
136 
137 OWNFUN(void,mfxownpj_EncodeHuffmanStateInit,(
138   ownpjEncodeHuffmanState* pState))
139 {
140   pState->uBitBuffer     = 0;
141   pState->nBitsValid     = 0;
142 
143   pState->nBE            = 0;
144   pState->nEndOfBlockRun = 0;
145 
146   mfxownsZero_8u(pState->pBEBuff,sizeof(pState->pBEBuff));
147 
148   return;
149 } /* mfxownpj_EncodeHuffmanStateInit() */
150 
151 
152 OWNFUN(IppStatus,mfxownpj_write_bits_jpeg,(
153   const unsigned int             uValue,
154   const int                      nBits,
155         Ipp8u*                   pDst,
156         int                      nDstLenBytes,
157         int*                     pDstCurrPos,
158         ownpjEncodeHuffmanState* pState))
159 {
160   int    nBitsValid;
161   Ipp32u uBitBuffer;
162   IppStatus status  = ippStsNoErr;
163 
164   if(nBits == 0)
165   {
166     return ippStsJPEGHuffTableErr;
167   }
168 
169   uBitBuffer = (Ipp32u)(uValue & MASK(nBits));
170   nBitsValid = pState->nBitsValid + nBits;
171 
172   uBitBuffer <<= 24 - nBitsValid;
173 
174   uBitBuffer |= (Ipp32u)pState->uBitBuffer;
175 
176   while(nBitsValid >= 8)
177   {
178     Ipp32u c = (Ipp32u)((uBitBuffer >> 16) & 0xFF);
179 
180     if(*pDstCurrPos >= nDstLenBytes)
181     {
182       status = ippStsJPEGOutOfBufErr;
183       goto Exit;
184     }
185 
186     *(pDst + *pDstCurrPos) = (Ipp8u)c;
187     (*pDstCurrPos)++;
188 
189     if(c == 0xff)
190     {
191       if(*pDstCurrPos == nDstLenBytes)
192       {
193         status = ippStsJPEGOutOfBufErr;
194         goto Exit;
195       }
196       *(pDst + *pDstCurrPos) = 0x00;
197       (*pDstCurrPos)++;
198     }
199 
200     uBitBuffer <<= 8;
201     nBitsValid  -= 8;
202   }
203 
204    /* update state variables */
205   pState->uBitBuffer = uBitBuffer;
206   pState->nBitsValid = nBitsValid;
207 
208 Exit:
209 
210   return status;
211 } /* mfxownpj_write_bits_jpeg() */
212 
213 
214 /* ---------------------- library functions definitions -------------------- */
215 
216 
217 /* ///////////////////////////////////////////////////////////////////////////
218 //  Name:
219 //    mfxiEncodeHuffmanRawTableInit_JPEG_8u
220 //
221 //  Purpose:
222 //    Build Huffman "raw" table from counted statistics of
223 //    Huffman symbols
224 //
225 //  Parameters:
226 //    pStatistics - pointer to Huffman symbols statistics
227 //    pListBits   - pointer to list of bits for Huffman codes
228 //    pListVals   - pointer to list of vals for Huffman codes
229 //
230 //  Returns:
231 //    IppStatus
232 //
233 //  Notes:
234 //
235 */
236 
237 IPPFUN(IppStatus, mfxiEncodeHuffmanRawTableInit_JPEG_8u, (
238   const int    pStatistics[256],
239         Ipp8u* pListBits,
240         Ipp8u* pListVals))
241 {
242   int   i;
243   int   j;
244   int   k;
245   int   v;
246   int   v1;
247   int   v2;
248   int   freq[257];
249   int   codesize[257];
250   int   others[257];
251   Ipp8u bits[MAX_CODE_LEN+1];
252 
253   IPP_BAD_PTR1_RET(pStatistics);
254   IPP_BAD_PTR2_RET(pListBits,pListVals);
255 
256   mfxownsCopy_8u((Ipp8u*)pStatistics,(Ipp8u*)&freq[0],sizeof(freq));
257   mfxownsZero_8u((Ipp8u*)&codesize,sizeof(codesize));
258   mfxownsZero_8u((Ipp8u*)&bits,sizeof(bits));
259   mfxownsSet_32s(-1,others,257);
260 
261   freq[256] = 1;
262 
263   for(;;)
264   {
265     /* find v1 for least value of freq[v1] > 0 */
266     v1 = -1;
267     v = 1000000000L;
268 
269     for(i = 0; i <= 256; i++)
270     {
271       if((freq[i] != 0) && (freq[i] <= v))
272       {
273         v = freq[i];
274         v1 = i;
275       }
276     }
277 
278     /* find v2 for next least value of freq[v2] > 0 */
279     v2 = -1;
280     v = 1000000000L;
281     for(i = 0; i <= 256; i++)
282     {
283       if((freq[i] != 0) && (freq[i] <= v) && (i != v1))
284       {
285         v = freq[i];
286         v2 = i;
287       }
288     }
289 
290     if(v2 < 0 || v1 < 0)
291     {
292       break;
293     }
294 
295     freq[v1] = freq[v1] + freq[v2];
296     freq[v2] = 0;
297 
298     codesize[v1]++;
299 
300     while(others[v1] >= 0)
301     {
302       v1 = others[v1];
303       codesize[v1]++;
304     }
305 
306     others[v1] = v2;
307 
308     codesize[v2]++;
309 
310     while(others[v2] >= 0)
311     {
312       v2 = others[v2];
313       codesize[v2]++;
314     }
315   }
316 
317 
318   /* count bits */
319   for(i = 0; i <= 256; i++)
320   {
321     if(codesize[i])
322     {
323       if(codesize[i] > MAX_CODE_LEN)
324       {
325         return ippStsJPEGHuffTableErr;
326       }
327 
328       bits[ codesize[i] ]++;
329     }
330   }
331 
332 
333   /* adjust bits */
334 
335   for(i = MAX_CODE_LEN; i > 16; i--)
336   {
337     while(bits[i] > 0)
338     {
339       j = i - 2;
340       while (bits[j] == 0)
341       {
342         j--;
343       }
344 
345       bits[i]   = (Ipp8u)(bits[i] - 2);
346       bits[i-1] = (Ipp8u)(bits[i - 1] + 1);
347       bits[j+1] = (Ipp8u)(bits[j + 1] + 2);
348       bits[j]   = (Ipp8u)(bits[j] - 1);
349     }
350   }
351 
352   while(bits[i] == 0)
353   {
354     i--;
355   }
356 
357   bits[i] = (Ipp8u)(bits[i] - 1);
358 
359 
360   /* sort input */
361 
362   mfxsCopy_8u(&bits[1],pListBits,16);
363 
364   k = 0;
365 
366   for(i = 1; i <= MAX_CODE_LEN; i++)
367   {
368     for(j = 0; j <= 255; j++)
369     {
370       if(codesize[j] == i)
371       {
372         pListVals[k] = (Ipp8u)j;
373         k++;
374       }
375     }
376   }
377 
378   return ippStsNoErr;
379 } /* mfxiEncodeHuffmanRawTableInit_JPEG_8u() */
380 
381 
382 /* ///////////////////////////////////////////////////////////////////////////
383 //  Name:
384 //    mfxiEncodeHuffmanSpecGetBufSize_JPEG_8u
385 //
386 //  Purpose:
387 //    get size of MfxiEncodeHuffmanSpec struct
388 //
389 //  Parameters:
390 //    pEncHuffSpecBufSize - where write size of buffer
391 //
392 //  Returns:
393 //    IppStatus
394 //
395 //  Notes:
396 //
397 */
398 
399 IPPFUN(IppStatus, mfxiEncodeHuffmanSpecGetBufSize_JPEG_8u, (
400   int* pEncHuffSpecBufSize))
401 {
402   IPP_BAD_PTR1_RET(pEncHuffSpecBufSize);
403 
404   *pEncHuffSpecBufSize = sizeof(ownpjEncodeHuffmanSpec);
405 
406   return ippStsNoErr;
407 } /* mfxiEncodeHuffmanSpecGetBufSize_JPEG_8u() */
408 
409 
410 /* ///////////////////////////////////////////////////////////////////////////
411 //  Name:
412 //    mfxiEncodeHuffmanSpecInit_JPEG_8u
413 //
414 //  Purpose:
415 //    Build Huffman table for encoder
416 //    in fast-to-use format from raw Huffman table
417 //
418 //  Parameters:
419 //    pListBits    - pointer to raw Huffman table bits
420 //    pListVals    - pointer to raw Huffman table vals
421 //    pEncHuffSpec - pointer to Huffman table to be initialized
422 //
423 //  Returns:
424 //    IppStatus
425 //
426 //  Notes:
427 //
428 */
429 
430 IPPFUN(IppStatus, mfxiEncodeHuffmanSpecInit_JPEG_8u, (
431   const Ipp8u*            pListBits,
432   const Ipp8u*            pListVals,
433   IppiEncodeHuffmanSpec*  pEncHuffSpec))
434 {
435   ownpjEncodeHuffmanSpec* pEncHuffTbl;
436 
437   IPP_BAD_PTR2_RET(pListBits,pListVals);
438   IPP_BAD_PTR1_RET(pEncHuffSpec);
439 
440   pEncHuffTbl = (ownpjEncodeHuffmanSpec*)pEncHuffSpec;
441 
442   return mfxownpj_EncodeHuffmanSpecInit(pListBits,pListVals,pEncHuffTbl);
443 } /* mfxiEncodeHuffmanSpecInit_JPEG_8u() */
444 
445 
446 /* ///////////////////////////////////////////////////////////////////////////
447 //  Name:
448 //    mfxiEncodeHuffmanStateGetBufSize_JPEG_8u
449 //
450 //  Purpose:
451 //    get size of IppiEncodeHuffmanState struct
452 //
453 //  Parameters:
454 //    pEncHuffStateBufSize - where write size of buffer
455 //
456 //  Returns:
457 //    IppStatus
458 //
459 //  Notes:
460 //
461 */
462 
463 IPPFUN(IppStatus, mfxiEncodeHuffmanStateGetBufSize_JPEG_8u, (
464   int*  pEncHuffStateBufSize))
465 {
466   IPP_BAD_PTR1_RET(pEncHuffStateBufSize);
467 
468   *pEncHuffStateBufSize = sizeof(ownpjEncodeHuffmanState);
469 
470   return ippStsNoErr;
471 } /* mfxiEncodeHuffmanStateGetBufSize_JPEG_8u() */
472 
473 
474 /* ///////////////////////////////////////////////////////////////////////////
475 //  Name:
476 //    mfxiEncodeHuffmanStateInit_JPEG_8u
477 //
478 //  Purpose:
479 //    Build IppiEncodeHuffmanState struct
480 //
481 //  Parameters:
482 //    pEncHuffState - pointer to IppiEncodeHuffmanState struct
483 //                    to be initialized
484 //
485 //  Returns:
486 //    IppStatus
487 //
488 //  Notes:
489 //
490 */
491 
492 IPPFUN(IppStatus, mfxiEncodeHuffmanStateInit_JPEG_8u, (
493   IppiEncodeHuffmanState*  pEncHuffState))
494 {
495   ownpjEncodeHuffmanState* pState;
496 
497   IPP_BAD_PTR1_RET(pEncHuffState);
498 
499   pState = (ownpjEncodeHuffmanState*)pEncHuffState;
500 
501   mfxownpj_EncodeHuffmanStateInit(pState);
502 
503   return ippStsNoErr;
504 } /* mfxiEncodeHuffmanStateInit_JPEG_8u() */
505 
506 
507 /* ///////////////////////////////////////////////////////////////////////////
508 //  Name:
509 //    mfxiEncodeHuffman8x8_JPEG_16s1u_C1
510 //
511 //  Purpose:
512 //    Huffman encode 8x8 block of quantized DCT coefs
513 //
514 //  Parameters:
515 //    pSrc            pointer to quantized DCT coefficients
516 //    pDst            pointer to output JPEG bitstream
517 //    DstLenBytes     bitstream length, in bytes
518 //    pDstCurrPos     current offset in bytes in buffer (in/out)
519 //    pLastDC         pointer to last DC coefs (in/out)
520 //    pEncHuffState   pointer to Huffman state struct
521 //    pDcTable        pointer to Huffman DC table
522 //    pAcTable        pointer to Huffman AC table
523 //    bFlushState     if non zero - only flush any pending bits from state
524 //
525 //  Returns:
526 //    IppStatus
527 //
528 //  Notes:
529 //
530 */
531 
532 IPPFUN(IppStatus, mfxiEncodeHuffman8x8_JPEG_16s1u_C1, (
533   const Ipp16s*                 pSrc,
534         Ipp8u*                  pDst,
535         int                     nDstLenBytes,
536         int*                    pDstCurrPos,
537         Ipp16s*                 pLastDC,
538   const IppiEncodeHuffmanSpec*  pDcTable,
539   const IppiEncodeHuffmanSpec*  pAcTable,
540         IppiEncodeHuffmanState* pEncHuffState,
541         int                     bFlushState))
542 {
543   int    i;
544   int    r;
545   int    rs;
546   unsigned int cs;
547   unsigned int uValue;
548   int    nBits;
549   int    data;
550   int    ssss;
551   ownpjEncodeHuffmanSpec*  dc_table = (ownpjEncodeHuffmanSpec*)pDcTable;
552   ownpjEncodeHuffmanSpec*  ac_table = (ownpjEncodeHuffmanSpec*)pAcTable;
553   ownpjEncodeHuffmanState* pState   = (ownpjEncodeHuffmanState*)pEncHuffState;
554   IppStatus status = ippStsNoErr;
555 
556   IPP_BAD_PTR1_RET(pDst);
557   IPP_BAD_SIZE_RET(nDstLenBytes);
558   IPP_BAD_PTR1_RET(pDstCurrPos);
559   IPP_BAD_PTR1_RET(pEncHuffState);
560 
561   if(bFlushState != 0)
562   {
563     status = mfxownpj_write_bits_jpeg(0x7f,7,pDst,nDstLenBytes,pDstCurrPos,pState);
564 
565     mfxownpj_EncodeHuffmanStateInit(pState);
566 
567     goto Exit;
568   }
569 
570   IPP_BAD_PTR1_RET(pSrc);
571   IPP_BAD_PTR1_RET(pLastDC);
572   IPP_BAD_PTR1_RET(pDcTable);
573   IPP_BAD_PTR1_RET(pAcTable);
574 
575 #if defined (_A6) || ( _IPP >= _IPP_W7 ) || ( _IPP32E >= _IPP32E_M7 )
576   status = mfxownpj_EncodeHuffman8x8_JPEG_16s1u_C1(
577            pSrc,
578            pDst,
579            nDstLenBytes,
580            pDstCurrPos,
581            pLastDC,
582            dc_table,
583            ac_table,
584            pState);
585 
586   if(ippStsNoErr == status)
587   {
588     goto Exit;
589   }
590 #endif
591 
592   /* Encode DC Coefficient */
593 
594   data = pSrc[0] - *pLastDC;
595 
596   *pLastDC = pSrc[0];
597 
598   if(data < 0)
599   {
600     if(data > -256)
601     {
602       ssss = mfxown_pj_csize[-data];
603     }
604     else
605     {
606       ssss = mfxown_pj_csize[(-data) >> 8] + 8;
607     }
608 
609     data -= 1;
610   }
611   else
612   {
613     if(data < 256)
614     {
615       ssss = mfxown_pj_csize[data];
616     }
617     else
618     {
619       ssss = mfxown_pj_csize[data >> 8] + 8;
620     }
621   }
622 
623   /* Encode Size of DC Coefficient */
624 
625   cs = dc_table->hcs[ssss];
626 
627   uValue = cs & 0xffff;
628   nBits  = cs >> 16;
629 
630   status = mfxownpj_write_bits_jpeg(
631     uValue,nBits,pDst,nDstLenBytes,pDstCurrPos,pState);
632 
633   if(ippStsNoErr != status)
634   {
635     goto Exit;
636   }
637 
638   /* Encode DC Coefficient Value                        */
639   /* (difference from previous value in this component) */
640 
641   if(ssss)
642   {
643     status = mfxownpj_write_bits_jpeg(
644       data,ssss,pDst,nDstLenBytes,pDstCurrPos,pState);
645 
646     if(ippStsNoErr != status)
647     {
648       goto Exit;
649     }
650   }
651 
652   /* Encode AC Coefficient(s) */
653 
654   r = 0;
655 
656   for(i = 1; i < DCTSIZE2; i++)
657   {
658     data = pSrc[mfxown_pj_izigzag_index[i]];
659 
660     if(data == 0)
661     {
662       r++; /* Increment run-length of zeroes */
663     }
664     else
665     {
666       while(r > 15)
667       {
668         cs = ac_table->hcs[0xf0];
669 
670         uValue = cs & 0xffff;
671         nBits  = cs >> 16;
672 
673         status = mfxownpj_write_bits_jpeg(
674           uValue,nBits,pDst,nDstLenBytes,pDstCurrPos,pState);
675 
676         if(ippStsNoErr != status)
677         {
678           goto Exit;
679         }
680 
681         r -= 16;
682       }
683 
684       if(data < 0)
685       {
686         if(data > -256)
687         {
688           ssss = mfxown_pj_csize[-data];
689         }
690         else
691         {
692           ssss = mfxown_pj_csize[(-data) >> 8] + 8;
693         }
694 
695         data -= 1;
696       }
697       else
698       {
699         if(data < 256)
700         {
701           ssss = mfxown_pj_csize[data];
702         }
703         else
704         {
705           ssss = mfxown_pj_csize[data >> 8] + 8;
706         }
707       }
708 
709       rs = (r << 4) + ssss;
710 
711       /* Encode run-length of zeros and size of first non-zero AC coeff */
712 
713       cs = ac_table->hcs[rs];
714 
715       uValue = cs & 0xffff;
716       nBits  = cs >> 16;
717 
718       status = mfxownpj_write_bits_jpeg(
719                  uValue,nBits,pDst,nDstLenBytes,pDstCurrPos,pState);
720 
721       if(ippStsNoErr != status)
722       {
723         goto Exit;
724       }
725 
726       /* Encode AC coefficient value and sign */
727 
728       if(ssss)
729       {
730         status = mfxownpj_write_bits_jpeg(
731           data,ssss,pDst,nDstLenBytes,pDstCurrPos,pState);
732 
733         if(ippStsNoErr != status)
734         {
735           goto Exit;
736         }
737       }
738 
739       r = 0;
740     } /* if data != 0 */
741   }   /* for i = 1...63 */
742 
743   if(r > 0)
744   {
745     /* Emit End Of Block code */
746 
747     cs = ac_table->hcs[0x00];
748 
749     uValue = cs & 0xffff;
750     nBits  = cs >> 16;
751 
752     status = mfxownpj_write_bits_jpeg(
753       uValue,nBits,pDst,nDstLenBytes,pDstCurrPos,pState);
754 
755     if(ippStsNoErr != status)
756     {
757       goto Exit;
758     }
759   }
760 
761 Exit:
762 
763   return status;
764 } /* mfxiEncodeHuffman8x8_JPEG_16s1u_C1() */
765 
766 
767 /* ///////////////////////////////////////////////////////////////////////////
768 //  Name:
769 //    mfxiGetHuffmanStatistics8x8_JPEG_16s_C1
770 //
771 //  Purpose:
772 //    gather huffman symbols statistics
773 //
774 //  Parameters:
775 //    pSrc               - pointer to input DCT coefficients block
776 //    pDcStatistics[256] - array for DC symbols statistics
777 //    pAcStatistics[265] - array for AC symbols statistics
778 //    pLastDC            - pointer to variable to store DC coefficient
779 //
780 //  Returns:
781 //    IppStatus
782 //
783 //  Notes:
784 //
785 */
786 
787 IPPFUN(IppStatus, mfxiGetHuffmanStatistics8x8_JPEG_16s_C1, (
788   const Ipp16s* pSrc,
789         int     pDcStatistics[256],
790         int     pAcStatistics[256],
791         Ipp16s* pLastDC))
792 {
793   int    i;
794   int    r;
795   int    rs;
796   int    data;
797   int    ssss;
798 
799   IPP_BAD_PTR1_RET(pSrc);
800   IPP_BAD_PTR2_RET(pDcStatistics,pAcStatistics);
801   IPP_BAD_PTR1_RET(pLastDC);
802 
803 
804   /* Encode DC Coefficient */
805   data = pSrc[0] - *pLastDC;
806 
807   *pLastDC = pSrc[0];
808 
809   if(data < 0)
810   {
811     if(data > -256)
812     {
813       ssss = mfxown_pj_csize[-data];
814     }
815     else
816     {
817       ssss = mfxown_pj_csize[(-data) >> 8] + 8;
818     }
819 
820   }
821   else
822   {
823     if(data < 256)
824     {
825       ssss = mfxown_pj_csize[data];
826     }
827     else
828     {
829       ssss = mfxown_pj_csize[data >> 8] + 8;
830     }
831   }
832 
833   if(ssss > 15)
834     return ippStsJPEGDCTRangeErr;
835 
836   /* Count huffval Size of DC Coefficient */
837   pDcStatistics[ssss]++;
838 
839 
840   /* Encode AC Coefficient(s) */
841   r = 0;
842 
843   for(i = 1; i < DCTSIZE2; i++)
844   {
845     data = pSrc[mfxown_pj_izigzag_index[i]];
846 
847     if(data == 0)
848     {
849       r++; /* Increment run-length of zeroes */
850     }
851     else
852     {
853       while(r > 15)
854       {
855         pAcStatistics[0xF0]++;
856 
857         r -= 16;
858       }
859 
860       if(data < 0)
861       {
862         if(data > -256)
863         {
864           ssss = mfxown_pj_csize[-data];
865         }
866         else
867         {
868           ssss = mfxown_pj_csize[(-data) >> 8] + 8;
869         }
870 
871         /* data -= 1; */
872       }
873       else
874       {
875         if(data < 256)
876         {
877           ssss = mfxown_pj_csize[data];
878         }
879         else
880         {
881           ssss = mfxown_pj_csize[data >> 8] + 8;
882         }
883       }
884 
885       if(ssss > 14)
886         return ippStsJPEGDCTRangeErr;
887 
888       rs = (r << 4) + ssss;
889 
890       /* Count run-length of zeros and size of first non-zero AC coeff */
891       pAcStatistics[rs]++;
892 
893       r = 0;
894     } /* if data != 0 */
895   }   /* for i = 1...63 */
896 
897   if(r > 0)
898   {
899     /* Emit End Of Block code */
900 
901     pAcStatistics[0]++;
902   }
903 
904   return ippStsNoErr;
905 } /* mfxiGetHuffmanStatistics8x8_JPEG_16s_C1() */
906 
907