The problem with ippiDCT8x8Inv_16s_C1I

The problem with ippiDCT8x8Inv_16s_C1I

Vladimir L.'s picture

Hello!

I use ipp function for decoding JPEG 4:1:1 and have the next problem.

From ijl source code

the ippi function ippiDCT8x8Inv_16s_C1I  has input data range [-256, 255] and depending on the quant matrix the result may be more 128.

but for example ippiYCbCr411ToRGBLS_MCU_16s8u_P3C3R which call after this need input data range [-128..127]

The data from real jpeg picture.

pSrcDst:

-135, 72, 17, 108, 40, -198, -170, 101,
-180, -20, 69, -96, -43, 192, 100, -91,
-115, 44, -81, 40, 66, 0, 115, 0,
69, -112, -37, 0, 0, 0, 0, 0,
30, -37, 0, -93, -113, 0, -171, 0,
-80, 116, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
120, 0, 158, 0, 186, 166, 0, 164

ippiDCT8x8Inv_16s_C1I(pSrcDst);

pSrcDst:

-52, -64, -46, -33, -74, -87, -32, -65,
-56, -64, -65, -62, -55, 24, -112, -51,
151, -58, -41, -67, -30, -131, -31, -13,
-150, 197, -64, -70, -38, -54, -25, -115,
45, 76, -38, -19, 124, -97, 208, 111,
-85, 92, -71, -64, 145, 78, -57, -22,
126, 8, -50, -75, 174, -68, -89, -38,
-43, 119, -61, -73, 169, -41, -56, -70

further

 ippiYCbCr411ToRGBLS_MCU_16s8u_P3C3R or my own kod  for convert 4:1:1 to 4:2:2

This leads to distorted output images (rgb,ycbcr422,...)

Thank you, Vladimir

18 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Sergey Khlystov (Intel)'s picture

Hi Vladimir,

Could you attach an example of JPEG file to test it here?

Regards,
Sergey 

Regards, Sergey
Vladimir L.'s picture

Hi, Sergey,

Attached file has 4:2:0/4:1:1 picture.

Vladimir.

Sergey Khlystov (Intel)'s picture

Vladimir, try again)). I see no attachment.

Regards,
Sergey 

Regards, Sergey
Vladimir L.'s picture

This is strange but I never attached files here (Add files and status 0%!).

Vladimir L.'s picture

done

Attachments: 

AttachmentSize
Download debug.jpg13.01 KB
Sergey Khlystov (Intel)'s picture

Vladimir,

I see no limitation of input data range for "ippiYCbCr411ToRGBLS_MCU_16s8u_P3C3R" function within the function code. May be the documentation is no so good.

So, you're saying that output image is bad. Do you use your own application? With uic_transcoder_con the attached image is decoded to BMP without evident problems.

Regards,
Sergey 

Regards, Sergey
Vladimir L.'s picture

Really the rgb has lightly different color from original picture. I see the same distinction when used my code for convert 4:2:0 in 4:2:2 (includied at cc_ss_decoder.c)  like this

OWNFUN(void) MY_YCbCr_420_to_YCbCr_422(
  JPEG_PROPERTIES* jprops,
  int              curxMCU,
  int              curyMCU)
{
  short*   inptr = (short*)jprops->MCUBuf;
  Ipp8u*   outptr;
  int      lineoffset = jprops->DIBLineBytes;
  IJL_RECT dibrect;
  IJLERR   jerr;
  int  LX;
  short d;
FILE* ifpBmp = NULL;
 
 jerr = CalcDIBRoi(&jprops->roi,16,16, curxMCU, curyMCU, 2, jprops->DIBWidth*2, jprops->DIBBytes, jprops->DIBWidth,jprops->DIBHeight,

              &(jprops->state.DIB_ptr), &dibrect);

  if(IJL_OK != jerr)  return;
  outptr = jprops->state.DIB_ptr;

/*

 IppiSize roi;
 Ipp8u buf[16*16*3 + CPU_CACHE_LINE-1]; // CPU_CACHE_LINE = 32
 const Ipp16s* pSrc[3];

Ipp8u* pDst = OWN_ALIGN_PTR(buf,CPU_CACHE_LINE);

roi.width  = dibrect.right; 

roi.height = dibrect.bottom; 

outptr = jprops->state.DIB_ptr;

pSrc[0] = &inptr[DCTSIZE2*0];
pSrc[1] = &inptr[DCTSIZE2*4];
pSrc[2] = &inptr[DCTSIZE2*5];

ippiSampleUp411LS_MCU_16s8u_P3C3R(pSrc,pDst,16*3);

*/

... my code convert 3 components to 4:2:2 ....

/*

 if(lineoffset < 0)      {
      lineoffset = -lineoffset;
      outptr = jprops->state.DIB_ptr - (dibrect.bottom - 1)*lineoffset;

      ippiMirror_8u_C3R(pDst,16*3,outptr,lineoffset,roi,ippAxsHorizontal);
    }
    else     {
      outptr = jprops->state.DIB_ptr;

      ippiCopy_8u_C3R(pDst,16*3,outptr,lineoffset,roi);
    }

*/ 

 return;
} /* MY_YCbCr_411_to_YCbCr_422() */

I thing that the difference produced in the IDTC ipp function, because the output coefficients can't be out of range [-128..128] . For this case we have [-150..208]. THis is wrong.

Vladimir

ps

With my point need check ipp IDCT with nonstandart Quant matrix which for my picture is

27, 18, 17, 27, 40, 66, 85, 101,
20, 20, 23, 32, 43, 96, 100, 91,
23, 22, 27, 40, 66, 95, 115, 93,
23, 28, 37, 48, 85, 144, 133, 103,
30, 37, 61, 93, 113, 181, 171, 128,
40, 58, 91, 106, 134, 173, 188, 153,
81, 106, 129, 144, 171, 201, 199, 168,
120, 153, 158, 163, 186, 166, 171, 164

Sergey Kostrov's picture

>>...the ippi function ippiDCT8x8Inv_16s_C1I has input data range [-256, 255]...

This is from ippdefs.h header file:

...
#define IPP_MIN_16S (-32768 )
#define IPP_MAX_16S ( 32767 )
...

and I also see a note in ippi.h header file that:

...
// Name: ippiDCT8x8Fwd_16s_C1, ippiDCT8x8Fwd_16s_C1I
// ippiDCT8x8Inv_16s_C1, ippiDCT8x8Inv_16s_C1I
// ippiDCT8x8Fwd_16s_C1R
// ippiDCT8x8Inv_16s_C1R
...
// Notes:
// Source data for inverse DCT functions must be the result of the forward DCT
// of data from the range [-256,255]
...

This is a strange limitation and I wonder if somebody could explain why is it Not [ -32768, 32767 ]?

IPP functions ippsDCTFwd and ippsDCTInv from DSP domain work with single-precision FP values ( allows wider dynamic range ) but if results are converted ( or normalized ) to a 16s range some loss will happen again.

Sergey Khlystov (Intel)'s picture

Vladimir,

What I see is:

1. The IDCT in the attached image is slightly different from what you've provided:

27  18  20  23  20  17  27  23
22  23  30  28  27  32  40  66
43  40  37  37  40  81  58  61
48  66  96  85 101 100 95  85
93  91 106 120 153 129 106 113
144 115 91 93 133 181 134 144
158 163 171 173 171 103 128 188
201 186 166 199 153 168 171 164
I have saved the attached image as "save target as" in Internet explorer. 

2. Besides uic_transcoder I tried a couple of JPEG decoders on your image (IrfanView, IJG's djpeg). Their results differ from each other by +/- 1 on some pixels. My be there some minor differences in IDCT methods.

3. I have seen with my own eyes )), that the IDCT from the file was fed to ippiQuantInvTableInit_JPEG_8u16u for table initialization. I am sure that that particular table was used in IDCT.

Do you have any reference image we strive to get as result?

Regards,
Sergey 

Regards, Sergey
Sergey Kostrov's picture

>>...Their results differ from each other by +/- 1 on some pixels...

It really looks like a rounding issue and it is enevitable. For example:

1.789 as float -> 2 as 16s, or

1.123 as float -> 1 as 16s

Vladimir L.'s picture

Thanks everybody,

need to think a little.

Vladimir

Vladimir L.'s picture

1. View debug.jpg by any standart program like "Windows Picture and Fax Viewer".

2. View by the same viewer the picture after ijl/ipp decoder of debug.jpg.

Te main difference in gray and black colors (Y component).  You can see this by quickly switching from one image to another.

Sergey Khlystov (Intel)'s picture

Good morning, Vladimir,

I have attached "debug.bmp" decoded from "debug.jpg" by uic_transcoder. Could you check this bmp file too? I cannot see the difference. Send your bmp to me to look also.

Regards,
Sergey 

Attachments: 

AttachmentSize
Download debug.bmp900.05 KB
Regards, Sergey
Vladimir L.'s picture

Our file.

Vladimir

Attachments: 

AttachmentSize
Download t422.bmp900.05 KB
Sergey Khlystov (Intel)'s picture

Yes, it's definitelty lighter. Could you compare the pipeline of decoding in your application and uic_transcoder? For transcoder it is (for debug.jpg):
    ippiDecodeHuffmanStateInit_JPEG_8u
    ippiDecodeHuffman8x8_JPEG_1u16s_C1
    ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R
    ippiSampleUpRowH2V2_Triangle_JPEG_8u_C1
    ippiYCbCrToRGB_JPEG_8u_P3C3R

I am wondering about usage of 'ippiYCbCr411ToRGBLS_MCU_16s8u_P3C3R'. May be it has difference coefficients to convert from YCbCr to RGB? Though, it must not be so.

Regards,
Sergey 

Regards, Sergey
Vladimir L.'s picture

Convertion to rgb wok fine, but we need convert 411 direct to 422 inside ijl. The ipp hasn't such possibility and we need do this by own code. The source of jpeg - ip camera and alhoritm "how she did it"  hidden from us.  We will try to use other ipp function but right now we don't know how to do it. I am sure that this is not simple task, because convertion Y component with over 128 values to range [-128..128] not trivial. May be need modify qaunt matrix or someting else.

Thanks again to Sergey's for discussion.

Vladimir

Vladimir L.'s picture

OK, I'l check.

Vladimir

Login to leave a comment.