MythTV  master
RTjpegN.cpp
Go to the documentation of this file.
1 /*
2  RTjpeg (C) Justin Schoeman 1998 (justin@suntiger.ee.up.ac.za)
3 
4  With modifications by:
5  (c) 1998, 1999 by Joerg Walter <trouble@moes.pmnet.uni-oldenburg.de>
6  and
7  (c) 1999 by Wim Taymans <wim.taymans@tvd.be>
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 
23 */
24 
25 #include <cstdio>
26 #include <cstdlib>
27 #include <cstring>
28 #include "RTjpegN.h"
29 
30 #ifdef MMX
38 #endif
39 
40 //#define SHOWBLOCK 1
41 #define BETTERCOMPRESSION 1
42 
43 static const unsigned char RTjpeg_ZZ[64]={
44 0,
45 8, 1,
46 2, 9, 16,
47 24, 17, 10, 3,
48 4, 11, 18, 25, 32,
49 40, 33, 26, 19, 12, 5,
50 6, 13, 20, 27, 34, 41, 48,
51 56, 49, 42, 35, 28, 21, 14, 7,
52 15, 22, 29, 36, 43, 50, 57,
53 58, 51, 44, 37, 30, 23,
54 31, 38, 45, 52, 59,
55 60, 53, 46, 39,
56 47, 54, 61,
57 62, 55,
58 63 };
59 
60 static const uint64_t RTjpeg_aan_tab[64]={
61 4294967296ULL, 5957222912ULL, 5611718144ULL, 5050464768ULL, 4294967296ULL, 3374581504ULL, 2324432128ULL, 1184891264ULL,
62 5957222912ULL, 8263040512ULL, 7783580160ULL, 7005009920ULL, 5957222912ULL, 4680582144ULL, 3224107520ULL, 1643641088ULL,
63 5611718144ULL, 7783580160ULL, 7331904512ULL, 6598688768ULL, 5611718144ULL, 4408998912ULL, 3036936960ULL, 1548224000ULL,
64 5050464768ULL, 7005009920ULL, 6598688768ULL, 5938608128ULL, 5050464768ULL, 3968072960ULL, 2733115392ULL, 1393296000ULL,
65 4294967296ULL, 5957222912ULL, 5611718144ULL, 5050464768ULL, 4294967296ULL, 3374581504ULL, 2324432128ULL, 1184891264ULL,
66 3374581504ULL, 4680582144ULL, 4408998912ULL, 3968072960ULL, 3374581504ULL, 2651326208ULL, 1826357504ULL, 931136000ULL,
67 2324432128ULL, 3224107520ULL, 3036936960ULL, 2733115392ULL, 2324432128ULL, 1826357504ULL, 1258030336ULL, 641204288ULL,
68 1184891264ULL, 1643641088ULL, 1548224000ULL, 1393296000ULL, 1184891264ULL, 931136000ULL, 641204288ULL, 326894240ULL,
69 };
70 
71 static const unsigned char RTjpeg_lum_quant_tbl[64] = {
72  16, 11, 10, 16, 24, 40, 51, 61,
73  12, 12, 14, 19, 26, 58, 60, 55,
74  14, 13, 16, 24, 40, 57, 69, 56,
75  14, 17, 22, 29, 51, 87, 80, 62,
76  18, 22, 37, 56, 68, 109, 103, 77,
77  24, 35, 55, 64, 81, 104, 113, 92,
78  49, 64, 78, 87, 103, 121, 120, 101,
79  72, 92, 95, 98, 112, 100, 103, 99
80  };
81 
82 static const unsigned char RTjpeg_chrom_quant_tbl[64] = {
83  17, 18, 24, 47, 99, 99, 99, 99,
84  18, 21, 26, 66, 99, 99, 99, 99,
85  24, 26, 56, 99, 99, 99, 99, 99,
86  47, 66, 99, 99, 99, 99, 99, 99,
87  99, 99, 99, 99, 99, 99, 99, 99,
88  99, 99, 99, 99, 99, 99, 99, 99,
89  99, 99, 99, 99, 99, 99, 99, 99,
90  99, 99, 99, 99, 99, 99, 99, 99
91  };
92 
93 #ifdef BETTERCOMPRESSION
94 
95 /*--------------------------------------------------*/
96 /* better encoding, but needs a lot more cpu time */
97 /* seems to be more effective than old method +lzo */
98 /* with this encoding lzo isn't efficient anymore */
99 /* there is still more potential for better */
100 /* encoding but that would need even more cputime */
101 /* anyway your mileage may vary */
102 /* */
103 /* written by Martin BIELY and Roman HOCHLEITNER */
104 /*--------------------------------------------------*/
105 
106 /* +++++++++++++++++++++++++++++++++++++++++++++++++++*/
107 /* Block to Stream (encoding) */
108 /* */
109 
110 int RTjpeg::b2s(const int16_t *data, int8_t *strm, uint8_t /*bt8*/)
111 {
112  int ci, co=1;
113  int16_t ZZvalue;
114  unsigned char bitten;
115  unsigned char bitoff;
116 
117  uint8_t *ustrm = (uint8_t *)strm;
118 #ifdef SHOWBLOCK
119 
120  int ii;
121  for (ii=0; ii < 64; ii++) {
122  fprintf(stdout, "%d ", data[RTjpeg_ZZ[ii]]);
123  }
124  fprintf(stdout, "\n\n");
125 
126 #endif
127 
128 // *strm++ = 0x10;
129 // *strm = 0x00;
130 //
131 // return 2;
132 
133  // first byte allways written
134  ustrm[0]=
135  (uint8_t)(data[RTjpeg_ZZ[0]]>254) ? 254:((data[RTjpeg_ZZ[0]]<0)?0:data[RTjpeg_ZZ[0]]);
136 
137 
138  ci=63;
139  while (data[RTjpeg_ZZ[ci]]==0 && ci>0) ci--;
140 
141  bitten = ((unsigned char)ci) << 2;
142 
143  if (ci==0) {
144  ustrm[1]= bitten;
145  co = 2;
146  return co;
147  }
148 
149  /* bitoff=0 because the high 6bit contain first non zero position */
150  bitoff = 0;
151  co = 1;
152 
153  for(; ci>0; ci--) {
154 
155  ZZvalue = data[RTjpeg_ZZ[ci]];
156 
157  switch(ZZvalue) {
158  case 0:
159  break;
160  case 1:
161  bitten |= (0x01<<bitoff);
162  break;
163  case -1:
164  bitten |= (0x03<<bitoff);
165  break;
166  default:
167  bitten |= (0x02<<bitoff);
168  goto HERZWEH;
169  break;
170  }
171 
172  if ( bitoff == 0 ) {
173  ustrm[co]= bitten;
174  bitten = 0;
175  bitoff = 8;
176  co++;
177  } /* "fall through" */
178  bitoff-=2;
179 
180  }
181 
182  /* ci must be 0 */
183  if (bitoff != 6) {
184 
185  ustrm[co]= bitten;
186  co++;
187 
188  }
189  goto BAUCHWEH;
190 
191 HERZWEH:
192 /* ci cannot be 0 */
193 /* correct bitoff to nibble boundaries */
194 
195  switch(bitoff){
196  case 4:
197  case 6:
198  bitoff = 0;
199  break;
200  case 2:
201  case 0:
202  ustrm[co]= bitten;
203  bitoff = 4;
204  co++;
205  bitten = 0; // clear half nibble values in bitten
206  break;
207  default:
208  break;
209  }
210 
211  for(; ci>0; ci--) {
212 
213  ZZvalue = data[RTjpeg_ZZ[ci]];
214 
215  if ( (ZZvalue > 7) || (ZZvalue < -7) ) {
216  bitten |= (0x08<<bitoff);
217  goto HIRNWEH;
218  }
219 
220  bitten |= (ZZvalue&0xf)<<bitoff;
221 
222  if ( bitoff == 0 ) {
223  ustrm[co]= bitten;
224  bitten = 0;
225  bitoff = 8;
226  co++;
227  } /* "fall thru" */
228  bitoff-=4;
229  }
230 
231  /* ci must be 0 */
232  if ( bitoff == 0 ) {
233  ustrm[co]= bitten;
234  co++;
235  }
236  goto BAUCHWEH;
237 
238 HIRNWEH:
239 
240  ustrm[co]= bitten;
241  co++;
242 
243 
244  /* bitting is over now we bite */
245  for(; ci>0; ci--) {
246 
247  ZZvalue = data[RTjpeg_ZZ[ci]];
248 
249  if (ZZvalue>0)
250  {
251  strm[co++]=(int8_t)(ZZvalue>127)?127:ZZvalue;
252  }
253  else
254  {
255  strm[co++]=(int8_t)(ZZvalue<-128)?-128:ZZvalue;
256  }
257 
258  }
259 
260 
261 BAUCHWEH:
262  /* we gotoo much now we are ill */
263 #ifdef SHOWBLOCK
264 {
265 int i;
266 fprintf(stdout, "\nco = '%d'\n", co);
267  for (i=0; i < co+2; i++) {
268  fprintf(stdout, "%d ", strm[i]);
269  }
270 fprintf(stdout, "\n\n");
271 }
272 #endif
273 
274  return co;
275 }
276 
277 /* +++++++++++++++++++++++++++++++++++++++++++++++++++*/
278 /* Stream to Block (decoding) */
279 /* */
280 
281 int RTjpeg::s2b(int16_t *data, const int8_t *strm, uint8_t /*bt8*/, int32_t *qtbla)
282 {
283  uint32_t *qtbl = (uint32_t *)qtbla;
284  int ci;
285  int co;
286  int i;
287  unsigned char bitten;
288  unsigned char bitoff;
289 
290  /* first byte always read */
291  i=RTjpeg_ZZ[0];
292  data[i]=((uint8_t)strm[0])*qtbl[i];
293 
294  /* we start at the behind */
295 
296  bitten = ((unsigned char)strm[1]) >> 2;
297  co = 63;
298  for(; co > bitten; co--) {
299 
300  data[RTjpeg_ZZ[co]] = 0;
301 
302  }
303 
304  if (co==0) {
305  ci = 2;
306  goto AUTOBAHN;
307  }
308 
309  /* we have to read the last 2 bits of the second byte */
310  ci=1;
311  bitoff = 0;
312 
313  for(; co>0; co--) {
314 
315  bitten = ((unsigned char)strm[ci]) >> bitoff;
316  bitten &= 0x03;
317 
318  i=RTjpeg_ZZ[co];
319 
320  switch( bitten ) {
321  case 0x03:
322  data[i]= -qtbl[i];
323  break;
324  case 0x02:
325  goto FUSSWEG;
326  break;
327  case 0x01:
328  data[i]= qtbl[i];
329  break;
330  case 0x00:
331  data[i]= 0;
332  break;
333  default:
334  break;
335  }
336 
337  if ( bitoff == 0 ) {
338  bitoff = 8;
339  ci++;
340  }
341  bitoff -= 2;
342  }
343  /* co is 0 now */
344  /* data is written properly */
345 
346  /* if bitoff!=6 then ci is the index, but should be the byte count, so we increment by 1 */
347  if (bitoff!=6) ci++;
348 
349  goto AUTOBAHN;
350 
351 
352 FUSSWEG:
353 /* correct bitoff to nibble */
354  switch(bitoff){
355  case 4:
356  case 6:
357  bitoff = 0;
358  break;
359  case 2:
360  case 0:
361  /* we have to read from the next byte */
362  ci++;
363  bitoff = 4;
364  break;
365  default:
366  break;
367  }
368 
369  for(; co>0; co--) {
370 
371  bitten = ((unsigned char)strm[ci]) >> bitoff;
372  bitten &= 0x0f;
373 
374  i=RTjpeg_ZZ[co];
375 
376  if ( bitten == 0x08 ) {
377  goto STRASSE;
378  }
379 
380  /* the compiler cannot do sign extension for signed nibbles */
381  if ( bitten & 0x08 ) {
382  bitten |= 0xf0;
383  }
384  /* the unsigned char bitten now is a valid signed char */
385 
386  data[i]=((signed char)bitten)*qtbl[i];
387 
388  if ( bitoff == 0 ) {
389  bitoff = 8;
390  ci++;
391  }
392  bitoff -= 4;
393  }
394  /* co is 0 */
395 
396  /* if bitoff!=4 then ci is the index, but should be the byte count, so we increment by 1 */
397  if (bitoff!=4) ci++;
398 
399  goto AUTOBAHN;
400 
401 STRASSE:
402  ci++;
403 
404  for(; co>0; co--) {
405  i=RTjpeg_ZZ[co];
406  data[i]=strm[ci++]*qtbl[i];
407  }
408 
409  /* ci now is the count, because it points to next element => no incrementing */
410 
411 AUTOBAHN:
412 
413 #ifdef SHOWBLOCK
414 fprintf(stdout, "\nci = '%d'\n", ci);
415  for (i=0; i < 64; i++) {
416  fprintf(stdout, "%d ", data[RTjpeg_ZZ[i]]);
417  }
418 fprintf(stdout, "\n\n");
419 #endif
420 
421  return ci;
422 }
423 
424 #else
425 
426 int RTjpeg::b2s(const int16_t *data, int8_t *strm, uint8_t bt8)
427 {
428  register int ci, co=1, tmp;
429  register int16_t ZZvalue;
430 
431 #ifdef SHOWBLOCK
432 
433  int ii;
434  for (ii=0; ii < 64; ii++) {
435  fprintf(stdout, "%d ", data[RTjpeg_ZZ[ii]]);
436  }
437  fprintf(stdout, "\n\n");
438 
439 #endif
440 
441  (uint8_t)strm[0]=(uint8_t)(data[RTjpeg_ZZ[0]]>254) ? 254:((data[RTjpeg_ZZ[0]]<0)?0:data[RTjpeg_ZZ[0]]);
442 
443  for(ci=1; ci<=bt8; ci++)
444  {
445  ZZvalue = data[RTjpeg_ZZ[ci]];
446 
447  if (ZZvalue>0)
448  {
449  strm[co++]=(int8_t)(ZZvalue>127)?127:ZZvalue;
450  }
451  else
452  {
453  strm[co++]=(int8_t)(ZZvalue<-128)?-128:ZZvalue;
454  }
455  }
456 
457  for(; ci<64; ci++)
458  {
459  ZZvalue = data[RTjpeg_ZZ[ci]];
460 
461  if (ZZvalue>0)
462  {
463  strm[co++]=(int8_t)(ZZvalue>63)?63:ZZvalue;
464  }
465  else if (ZZvalue<0)
466  {
467  strm[co++]=(int8_t)(ZZvalue<-64)?-64:ZZvalue;
468  }
469  else /* compress zeros */
470  {
471  tmp=ci;
472  do
473  {
474  ci++;
475  } while((ci<64)&&(data[RTjpeg_ZZ[ci]]==0));
476 
477  strm[co++]=(int8_t)(63+(ci-tmp));
478  ci--;
479  }
480  }
481  return (int)co;
482 }
483 
484 int RTjpeg::s2b(int16_t *data, const int8_t *strm, uint8_t bt8, uint32_t *qtbla)
485 {
486  uint32_t *qtbl = (uint32_t *)qtbla;
487  int ci=1, co=1, tmp;
488  register int i;
489 
490  i=RTjpeg_ZZ[0];
491  data[i]=((uint8_t)strm[0])*qtbl[i];
492 
493  for(co=1; co<=bt8; co++)
494  {
495  i=RTjpeg_ZZ[co];
496  data[i]=strm[ci++]*qtbl[i];
497  }
498 
499  for(; co<64; co++)
500  {
501  if (strm[ci]>63)
502  {
503  tmp=co+strm[ci]-63;
504  for(; co<tmp; co++)data[RTjpeg_ZZ[co]]=0;
505  co--;
506  } else
507  {
508  i=RTjpeg_ZZ[co];
509  data[i]=strm[ci]*qtbl[i];
510  }
511  ci++;
512  }
513  return (int)ci;
514 }
515 #endif
516 
517 #ifdef MMX
519 {
520  int i;
521  typedef union { int16_t *int16; int32_t *int32; } P16_32;
522  P16_32 qtbl;
523 
524  qtbl.int32 = lqt;
525  for (i = 0; i < 64; i++)
526  qtbl.int16[i] = static_cast<int16_t>(lqt[i]);
527 
528  // cppcheck-suppress unreadVariable
529  qtbl.int32 = cqt;
530  for (i = 0; i < 64; i++)
531  qtbl.int16[i] = static_cast<int16_t>(cqt[i]);
532 }
533 
534 void RTjpeg::Quant(int16_t *_block, int32_t *qtbl)
535 {
536  int i;
537  mmx_t *bl, *ql;
538 
539 
540  ql=(mmx_t *)qtbl;
541  bl=(mmx_t *)_block;
542 
543  movq_m2r(RTjpeg_ones, mm6);
544  movq_m2r(RTjpeg_half, mm7);
545 
546  for(i=16; i; i--)
547  {
548  movq_m2r(*(ql++), mm0); /* quant vals (4) */
549  movq_m2r(*bl, mm2); /* block vals (4) */
550  movq_r2r(mm0, mm1);
551  movq_r2r(mm2, mm3);
552 
553  punpcklwd_r2r(mm6, mm0); /* 1 qb 1 qa */
554  punpckhwd_r2r(mm6, mm1); /* 1 qd 1 qc */
555 
556  punpcklwd_r2r(mm7, mm2); /* 32767 bb 32767 ba */
557  punpckhwd_r2r(mm7, mm3); /* 32767 bd 32767 bc */
558 
559  pmaddwd_r2r(mm2, mm0); /* 32767+bb*qb 32767+ba*qa */
560  pmaddwd_r2r(mm3, mm1); /* 32767+bd*qd 32767+bc*qc */
561 
562  psrad_i2r(16, mm0);
563  psrad_i2r(16, mm1);
564 
565  packssdw_r2r(mm1, mm0);
566 
567  movq_r2m(mm0, *(bl++));
568  }
569 }
570 #else
571 void RTjpeg::QuantInit()
572 {
573 }
574 
575 void RTjpeg::Quant(int16_t *_block, int32_t *qtbl)
576 {
577  int i;
578 
579  for(i=0; i<64; i++)
580  _block[i]=(int16_t)((_block[i]*qtbl[i]+32767)>>16);
581 }
582 #endif
583 
584 /*
585  * Perform the forward DCT on one block of samples.
586  */
587 #ifndef MMX
588 #define FIX_0_382683433 ((int32_t) 98) /* FIX(0.382683433) */
589 #define FIX_0_541196100 ((int32_t) 139) /* FIX(0.541196100) */
590 #define FIX_0_707106781 ((int32_t) 181) /* FIX(0.707106781) */
591 #define FIX_1_306562965 ((int32_t) 334) /* FIX(1.306562965) */
592 
593 #define DESCALE10(x) (int16_t)( ((x)+128) >> 8)
594 #define DESCALE20(x) (int16_t)(((x)+32768) >> 16)
595 #define D_MULTIPLY(var,const) ((int32_t) ((var) * (const)))
596 #endif
597 
599 {
600  int i;
601 
602  for(i = 0; i < 64; i++)
603  {
604  lqt[i] = (((uint64_t)lqt[i] << 32) / RTjpeg_aan_tab[i]);
605  cqt[i] = (((uint64_t)cqt[i] << 32) / RTjpeg_aan_tab[i]);
606  }
607 }
608 
609 void RTjpeg::DctY(uint8_t *idata, int rskip)
610 {
611 #ifndef MMX
612  int32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
613  int32_t tmp10, tmp11, tmp12, tmp13;
614  int32_t z1, z2, z3, z4, z5, z11, z13;
615  uint8_t *idataptr;
616  int16_t *odataptr;
617  int32_t *wsptr;
618  int ctr;
619 
620 
621  idataptr = idata;
622  wsptr = ws;
623  for (ctr = 7; ctr >= 0; ctr--) {
624  tmp0 = idataptr[0] + idataptr[7];
625  tmp7 = idataptr[0] - idataptr[7];
626  tmp1 = idataptr[1] + idataptr[6];
627  tmp6 = idataptr[1] - idataptr[6];
628  tmp2 = idataptr[2] + idataptr[5];
629  tmp5 = idataptr[2] - idataptr[5];
630  tmp3 = idataptr[3] + idataptr[4];
631  tmp4 = idataptr[3] - idataptr[4];
632 
633  tmp10 = (tmp0 + tmp3); /* phase 2 */
634  tmp13 = tmp0 - tmp3;
635  tmp11 = (tmp1 + tmp2);
636  tmp12 = tmp1 - tmp2;
637 
638  wsptr[0] = (tmp10 + tmp11)<<8; /* phase 3 */
639  wsptr[4] = (tmp10 - tmp11)<<8;
640 
641  z1 = D_MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
642  wsptr[2] = (tmp13<<8) + z1; /* phase 5 */
643  wsptr[6] = (tmp13<<8) - z1;
644 
645  tmp10 = tmp4 + tmp5; /* phase 2 */
646  tmp11 = tmp5 + tmp6;
647  tmp12 = tmp6 + tmp7;
648 
649  z5 = D_MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
650  z2 = D_MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
651  z4 = D_MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
652  z3 = D_MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
653 
654  z11 = (tmp7<<8) + z3; /* phase 5 */
655  z13 = (tmp7<<8) - z3;
656 
657  wsptr[5] = z13 + z2; /* phase 6 */
658  wsptr[3] = z13 - z2;
659  wsptr[1] = z11 + z4;
660  wsptr[7] = z11 - z4;
661 
662  idataptr += rskip<<3; /* advance pointer to next row */
663  wsptr += 8;
664  }
665 
666  wsptr = ws;
667  odataptr = block;
668  for (ctr = 7; ctr >= 0; ctr--) {
669  tmp0 = wsptr[0] + wsptr[56];
670  tmp7 = wsptr[0] - wsptr[56];
671  tmp1 = wsptr[8] + wsptr[48];
672  tmp6 = wsptr[8] - wsptr[48];
673  tmp2 = wsptr[16] + wsptr[40];
674  tmp5 = wsptr[16] - wsptr[40];
675  tmp3 = wsptr[24] + wsptr[32];
676  tmp4 = wsptr[24] - wsptr[32];
677 
678  tmp10 = tmp0 + tmp3; /* phase 2 */
679  tmp13 = tmp0 - tmp3;
680  tmp11 = tmp1 + tmp2;
681  tmp12 = tmp1 - tmp2;
682 
683  odataptr[0] = DESCALE10(tmp10 + tmp11); /* phase 3 */
684  odataptr[32] = DESCALE10(tmp10 - tmp11);
685 
686  z1 = D_MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
687  odataptr[16] = DESCALE20((tmp13<<8) + z1); /* phase 5 */
688  odataptr[48] = DESCALE20((tmp13<<8) - z1);
689 
690  tmp10 = tmp4 + tmp5; /* phase 2 */
691  tmp11 = tmp5 + tmp6;
692  tmp12 = tmp6 + tmp7;
693 
694  z5 = D_MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
695  z2 = D_MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
696  z4 = D_MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
697  z3 = D_MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
698 
699  z11 = (tmp7<<8) + z3; /* phase 5 */
700  z13 = (tmp7<<8) - z3;
701 
702  odataptr[40] = DESCALE20(z13 + z2); /* phase 6 */
703  odataptr[24] = DESCALE20(z13 - z2);
704  odataptr[8] = DESCALE20(z11 + z4);
705  odataptr[56] = DESCALE20(z11 - z4);
706 
707  odataptr++; /* advance pointer to next column */
708  wsptr++;
709 
710  }
711 #else
712  volatile mmx_t tmp6, tmp7;
713  mmx_t *dataptr = (mmx_t *)block;
714  mmx_t *idata2 = (mmx_t *)idata;
715 
716 
717  // first copy the input 8 bit to the destination 16 bits
718 
719  movq_m2r(RTjpeg_zero, mm2);
720 
721  movq_m2r(*idata2, mm0);
722  movq_r2r(mm0, mm1);
723 
724  punpcklbw_r2r(mm2, mm0);
725  movq_r2m(mm0, *(dataptr));
726 
727  punpckhbw_r2r(mm2, mm1);
728  movq_r2m(mm1, *(dataptr+1));
729 
730  idata2 += rskip;
731 
732  movq_m2r(*idata2, mm0);
733  movq_r2r(mm0, mm1);
734 
735  punpcklbw_r2r(mm2, mm0);
736  movq_r2m(mm0, *(dataptr+2));
737 
738  punpckhbw_r2r(mm2, mm1);
739  movq_r2m(mm1, *(dataptr+3));
740 
741  idata2 += rskip;
742 
743  movq_m2r(*idata2, mm0);
744  movq_r2r(mm0, mm1);
745 
746  punpcklbw_r2r(mm2, mm0);
747  movq_r2m(mm0, *(dataptr+4));
748 
749  punpckhbw_r2r(mm2, mm1);
750  movq_r2m(mm1, *(dataptr+5));
751 
752  idata2 += rskip;
753 
754  movq_m2r(*idata2, mm0);
755  movq_r2r(mm0, mm1);
756 
757  punpcklbw_r2r(mm2, mm0);
758  movq_r2m(mm0, *(dataptr+6));
759 
760  punpckhbw_r2r(mm2, mm1);
761  movq_r2m(mm1, *(dataptr+7));
762 
763  idata2 += rskip;
764 
765  movq_m2r(*idata2, mm0);
766  movq_r2r(mm0, mm1);
767 
768  punpcklbw_r2r(mm2, mm0);
769  movq_r2m(mm0, *(dataptr+8));
770 
771  punpckhbw_r2r(mm2, mm1);
772  movq_r2m(mm1, *(dataptr+9));
773 
774  idata2 += rskip;
775 
776  movq_m2r(*idata2, mm0);
777  movq_r2r(mm0, mm1);
778 
779  punpcklbw_r2r(mm2, mm0);
780  movq_r2m(mm0, *(dataptr+10));
781 
782  punpckhbw_r2r(mm2, mm1);
783  movq_r2m(mm1, *(dataptr+11));
784 
785  idata2 += rskip;
786 
787  movq_m2r(*idata2, mm0);
788  movq_r2r(mm0, mm1);
789 
790  punpcklbw_r2r(mm2, mm0);
791  movq_r2m(mm0, *(dataptr+12));
792 
793  punpckhbw_r2r(mm2, mm1);
794  movq_r2m(mm1, *(dataptr+13));
795 
796  idata2 += rskip;
797 
798  movq_m2r(*idata2, mm0);
799  movq_r2r(mm0, mm1);
800 
801  punpcklbw_r2r(mm2, mm0);
802  movq_r2m(mm0, *(dataptr+14));
803 
804  punpckhbw_r2r(mm2, mm1);
805  movq_r2m(mm1, *(dataptr+15));
806 
807 /* Start Transpose to do calculations on rows */
808 
809  movq_m2r(*(dataptr+9), mm7); // m03:m02|m01:m00 - first line (line 4)and copy into m5
810 
811  movq_m2r(*(dataptr+13), mm6); // m23:m22|m21:m20 - third line (line 6)and copy into m2
812  movq_r2r(mm7, mm5);
813 
814  punpcklwd_m2r(*(dataptr+11), mm7); // m11:m01|m10:m00 - interleave first and second lines
815  movq_r2r(mm6, mm2);
816 
817  punpcklwd_m2r(*(dataptr+15), mm6); // m31:m21|m30:m20 - interleave third and fourth lines
818  movq_r2r(mm7, mm1);
819 
820  movq_m2r(*(dataptr+11), mm3); // m13:m13|m11:m10 - second line
821  punpckldq_r2r(mm6, mm7); // m30:m20|m10:m00 - interleave to produce result 1
822 
823  movq_m2r(*(dataptr+15), mm0); // m13:m13|m11:m10 - fourth line
824  punpckhdq_r2r(mm6, mm1); // m31:m21|m11:m01 - interleave to produce result 2
825 
826  movq_r2m(mm7,*(dataptr+9)); // write result 1
827  punpckhwd_r2r(mm3, mm5); // m13:m03|m12:m02 - interleave first and second lines
828 
829  movq_r2m(mm1,*(dataptr+11)); // write result 2
830  punpckhwd_r2r(mm0, mm2); // m33:m23|m32:m22 - interleave third and fourth lines
831 
832  movq_r2r(mm5, mm1);
833  punpckldq_r2r(mm2, mm5); // m32:m22|m12:m02 - interleave to produce result 3
834 
835  movq_m2r(*(dataptr+1), mm0); // m03:m02|m01:m00 - first line, 4x4
836  punpckhdq_r2r(mm2, mm1); // m33:m23|m13:m03 - interleave to produce result 4
837 
838  movq_r2m(mm5,*(dataptr+13)); // write result 3
839 
840  // last 4x4 done
841 
842  movq_r2m(mm1, *(dataptr+15)); // write result 4, last 4x4
843 
844  movq_m2r(*(dataptr+5), mm2); // m23:m22|m21:m20 - third line
845  movq_r2r(mm0, mm6);
846 
847  punpcklwd_m2r(*(dataptr+3), mm0); // m11:m01|m10:m00 - interleave first and second lines
848  movq_r2r(mm2, mm7);
849 
850  punpcklwd_m2r(*(dataptr+7), mm2); // m31:m21|m30:m20 - interleave third and fourth lines
851  movq_r2r(mm0, mm4);
852 
853  //
854  movq_m2r(*(dataptr+8), mm1); // n03:n02|n01:n00 - first line
855  punpckldq_r2r(mm2, mm0); // m30:m20|m10:m00 - interleave to produce first result
856 
857  movq_m2r(*(dataptr+12), mm3); // n23:n22|n21:n20 - third line
858  punpckhdq_r2r(mm2, mm4); // m31:m21|m11:m01 - interleave to produce second result
859 
860  punpckhwd_m2r(*(dataptr+3), mm6); // m13:m03|m12:m02 - interleave first and second lines
861  movq_r2r(mm1, mm2); // copy first line
862 
863  punpckhwd_m2r(*(dataptr+7), mm7); // m33:m23|m32:m22 - interleave third and fourth lines
864  movq_r2r(mm6, mm5); // copy first intermediate result
865 
866  movq_r2m(mm0, *(dataptr+8)); // write result 1
867  punpckhdq_r2r(mm7, mm5); // m33:m23|m13:m03 - produce third result
868 
869  punpcklwd_m2r(*(dataptr+10), mm1); // n11:n01|n10:n00 - interleave first and second lines
870  movq_r2r(mm3, mm0); // copy third line
871 
872  punpckhwd_m2r(*(dataptr+10), mm2); // n13:n03|n12:n02 - interleave first and second lines
873 
874  movq_r2m(mm4, *(dataptr+10)); // write result 2 out
875  punpckldq_r2r(mm7, mm6); // m32:m22|m12:m02 - produce fourth result
876 
877  punpcklwd_m2r(*(dataptr+14), mm3); // n31:n21|n30:n20 - interleave third and fourth lines
878  movq_r2r(mm1, mm4);
879 
880  movq_r2m(mm6, *(dataptr+12)); // write result 3 out
881  punpckldq_r2r(mm3, mm1); // n30:n20|n10:n00 - produce first result
882 
883  punpckhwd_m2r(*(dataptr+14), mm0); // n33:n23|n32:n22 - interleave third and fourth lines
884  movq_r2r(mm2, mm6);
885 
886  movq_r2m(mm5, *(dataptr+14)); // write result 4 out
887  punpckhdq_r2r(mm3, mm4); // n31:n21|n11:n01- produce second result
888 
889  movq_r2m(mm1, *(dataptr+1)); // write result 5 out - (first result for other 4 x 4 block)
890  punpckldq_r2r(mm0, mm2); // n32:n22|n12:n02- produce third result
891 
892  movq_r2m(mm4, *(dataptr+3)); // write result 6 out
893  punpckhdq_r2r(mm0, mm6); // n33:n23|n13:n03 - produce fourth result
894 
895  movq_r2m(mm2, *(dataptr+5)); // write result 7 out
896 
897  movq_m2r(*dataptr, mm0); // m03:m02|m01:m00 - first line, first 4x4
898 
899  movq_r2m(mm6, *(dataptr+7)); // write result 8 out
900 
901 
902 // Do first 4x4 quadrant, which is used in the beginning of the DCT:
903 
904  movq_m2r(*(dataptr+4), mm7); // m23:m22|m21:m20 - third line
905  movq_r2r(mm0, mm2);
906 
907  punpcklwd_m2r(*(dataptr+2), mm0); // m11:m01|m10:m00 - interleave first and second lines
908  movq_r2r(mm7, mm4);
909 
910  punpcklwd_m2r(*(dataptr+6), mm7); // m31:m21|m30:m20 - interleave third and fourth lines
911  movq_r2r(mm0, mm1);
912 
913  movq_m2r(*(dataptr+2), mm6); // m13:m12|m11:m10 - second line
914  punpckldq_r2r(mm7, mm0); // m30:m20|m10:m00 - interleave to produce result 1
915 
916  movq_m2r(*(dataptr+6), mm5); // m33:m32|m31:m30 - fourth line
917  punpckhdq_r2r(mm7, mm1); // m31:m21|m11:m01 - interleave to produce result 2
918 
919  movq_r2r(mm0, mm7); // write result 1
920  punpckhwd_r2r(mm6, mm2); // m13:m03|m12:m02 - interleave first and second lines
921 
922  psubw_m2r(*(dataptr+14), mm7); // tmp07=x0-x7 /* Stage 1 */
923  movq_r2r(mm1, mm6); // write result 2
924 
925  paddw_m2r(*(dataptr+14), mm0); // tmp00=x0+x7 /* Stage 1 */
926  punpckhwd_r2r(mm5, mm4); // m33:m23|m32:m22 - interleave third and fourth lines
927 
928  paddw_m2r(*(dataptr+12), mm1); // tmp01=x1+x6 /* Stage 1 */
929  movq_r2r(mm2, mm3); // copy first intermediate result
930 
931  psubw_m2r(*(dataptr+12), mm6); // tmp06=x1-x6 /* Stage 1 */
932  punpckldq_r2r(mm4, mm2); // m32:m22|m12:m02 - interleave to produce result 3
933 
934  movq_r2m(mm7, tmp7);
935  movq_r2r(mm2, mm5); // write result 3
936 
937  movq_r2m(mm6, tmp6);
938  punpckhdq_r2r(mm4, mm3); // m33:m23|m13:m03 - interleave to produce result 4
939 
940  paddw_m2r(*(dataptr+10), mm2); // tmp02=x2+5 /* Stage 1 */
941  movq_r2r(mm3, mm4); // write result 4
942 
943 /************************************************************************************************
944  End of Transpose
945 ************************************************************************************************/
946 
947 
948  paddw_m2r(*(dataptr+8), mm3); // tmp03=x3+x4 /* stage 1*/
949  movq_r2r(mm0, mm7);
950 
951  psubw_m2r(*(dataptr+8), mm4); // tmp04=x3-x4 /* stage 1*/
952  movq_r2r(mm1, mm6);
953 
954  paddw_r2r(mm3, mm0); // tmp10 = tmp00 + tmp03 /* even 2 */
955  psubw_r2r(mm3, mm7); // tmp13 = tmp00 - tmp03 /* even 2 */
956 
957  psubw_r2r(mm2, mm6); // tmp12 = tmp01 - tmp02 /* even 2 */
958  paddw_r2r(mm2, mm1); // tmp11 = tmp01 + tmp02 /* even 2 */
959 
960  psubw_m2r(*(dataptr+10), mm5); // tmp05=x2-x5 /* stage 1*/
961  paddw_r2r(mm7, mm6); // tmp12 + tmp13
962 
963  /* stage 3 */
964 
965  movq_m2r(tmp6, mm2);
966  movq_r2r(mm0, mm3);
967 
968  psllw_i2r(2, mm6); // m8 * 2^2
969  paddw_r2r(mm1, mm0);
970 
971  pmulhw_m2r(RTjpeg_C4, mm6); // z1
972  psubw_r2r(mm1, mm3);
973 
974  movq_r2m(mm0, *dataptr);
975  movq_r2r(mm7, mm0);
976 
977  /* Odd part */
978  movq_r2m(mm3, *(dataptr+8));
979  paddw_r2r(mm5, mm4); // tmp10
980 
981  movq_m2r(tmp7, mm3);
982  paddw_r2r(mm6, mm0); // tmp32
983 
984  paddw_r2r(mm2, mm5); // tmp11
985  psubw_r2r(mm6, mm7); // tmp33
986 
987  movq_r2m(mm0, *(dataptr+4));
988  paddw_r2r(mm3, mm2); // tmp12
989 
990  /* stage 4 */
991 
992  movq_r2m(mm7, *(dataptr+12));
993  movq_r2r(mm4, mm1); // copy of tmp10
994 
995  psubw_r2r(mm2, mm1); // tmp10 - tmp12
996  psllw_i2r(2, mm4); // m8 * 2^2
997 
998  movq_m2r(RTjpeg_C2mC6, mm0);
999  psllw_i2r(2, mm1);
1000 
1001  pmulhw_m2r(RTjpeg_C6, mm1); // z5
1002  psllw_i2r(2, mm2);
1003 
1004  pmulhw_r2r(mm0, mm4); // z5
1005 
1006  /* stage 5 */
1007 
1008  pmulhw_m2r(RTjpeg_C2pC6, mm2);
1009  psllw_i2r(2, mm5);
1010 
1011  pmulhw_m2r(RTjpeg_C4, mm5); // z3
1012  movq_r2r(mm3, mm0); // copy tmp7
1013 
1014  movq_m2r(*(dataptr+1), mm7);
1015  paddw_r2r(mm1, mm4); // z2
1016 
1017  paddw_r2r(mm1, mm2); // z4
1018 
1019  paddw_r2r(mm5, mm0); // z11
1020  psubw_r2r(mm5, mm3); // z13
1021 
1022  /* stage 6 */
1023 
1024  movq_r2r(mm3, mm5); // copy z13
1025  psubw_r2r(mm4, mm3); // y3=z13 - z2
1026 
1027  paddw_r2r(mm4, mm5); // y5=z13 + z2
1028  movq_r2r(mm0, mm6); // copy z11
1029 
1030  movq_r2m(mm3, *(dataptr+6)); //save y3
1031  psubw_r2r(mm2, mm0); // y7=z11 - z4
1032 
1033  movq_r2m(mm5, *(dataptr+10)); //save y5
1034  paddw_r2r(mm2, mm6); // y1=z11 + z4
1035 
1036  movq_r2m(mm0, *(dataptr+14)); //save y7
1037 
1038  /************************************************
1039  * End of 1st 4 rows
1040  ************************************************/
1041 
1042  movq_m2r(*(dataptr+3), mm1); // load x1 /* stage 1 */
1043  movq_r2r(mm7, mm0); // copy x0
1044 
1045  movq_r2m(mm6, *(dataptr+2)); //save y1
1046 
1047  movq_m2r(*(dataptr+5), mm2); // load x2 /* stage 1 */
1048  movq_r2r(mm1, mm6); // copy x1
1049 
1050  paddw_m2r(*(dataptr+15), mm0); // tmp00 = x0 + x7
1051 
1052  movq_m2r(*(dataptr+7), mm3); // load x3 /* stage 1 */
1053  movq_r2r(mm2, mm5); // copy x2
1054 
1055  psubw_m2r(*(dataptr+15), mm7); // tmp07 = x0 - x7
1056  movq_r2r(mm3, mm4); // copy x3
1057 
1058  paddw_m2r(*(dataptr+13), mm1); // tmp01 = x1 + x6
1059 
1060  movq_r2m(mm7, tmp7); // save tmp07
1061  movq_r2r(mm0, mm7); // copy tmp00
1062 
1063  psubw_m2r(*(dataptr+13), mm6); // tmp06 = x1 - x6
1064 
1065  /* stage 2, Even Part */
1066 
1067  paddw_m2r(*(dataptr+9), mm3); // tmp03 = x3 + x4
1068 
1069  movq_r2m(mm6, tmp6); // save tmp07
1070  movq_r2r(mm1, mm6); // copy tmp01
1071 
1072  paddw_m2r(*(dataptr+11), mm2); // tmp02 = x2 + x5
1073  paddw_r2r(mm3, mm0); // tmp10 = tmp00 + tmp03
1074 
1075  psubw_r2r(mm3, mm7); // tmp13 = tmp00 - tmp03
1076 
1077  psubw_m2r(*(dataptr+9), mm4); // tmp04 = x3 - x4
1078  psubw_r2r(mm2, mm6); // tmp12 = tmp01 - tmp02
1079 
1080  paddw_r2r(mm2, mm1); // tmp11 = tmp01 + tmp02
1081 
1082  psubw_m2r(*(dataptr+11), mm5); // tmp05 = x2 - x5
1083  paddw_r2r(mm7, mm6); // tmp12 + tmp13
1084 
1085  /* stage 3, Even and stage 4 & 5 even */
1086 
1087  movq_m2r(tmp6, mm2); // load tmp6
1088  movq_r2r(mm0, mm3); // copy tmp10
1089 
1090  psllw_i2r(2, mm6); // shift z1
1091  paddw_r2r(mm1, mm0); // y0=tmp10 + tmp11
1092 
1093  pmulhw_m2r(RTjpeg_C4, mm6); // z1
1094  psubw_r2r(mm1, mm3); // y4=tmp10 - tmp11
1095 
1096  movq_r2m(mm0, *(dataptr+1)); //save y0
1097  movq_r2r(mm7, mm0); // copy tmp13
1098 
1099  /* odd part */
1100 
1101  movq_r2m(mm3, *(dataptr+9)); //save y4
1102  paddw_r2r(mm5, mm4); // tmp10 = tmp4 + tmp5
1103 
1104  movq_m2r(tmp7, mm3); // load tmp7
1105  paddw_r2r(mm6, mm0); // tmp32 = tmp13 + z1
1106 
1107  paddw_r2r(mm2, mm5); // tmp11 = tmp5 + tmp6
1108  psubw_r2r(mm6, mm7); // tmp33 = tmp13 - z1
1109 
1110  movq_r2m(mm0, *(dataptr+5)); //save y2
1111  paddw_r2r(mm3, mm2); // tmp12 = tmp6 + tmp7
1112 
1113  /* stage 4 */
1114 
1115  movq_r2m(mm7, *(dataptr+13)); //save y6
1116  movq_r2r(mm4, mm1); // copy tmp10
1117 
1118  psubw_r2r(mm2, mm1); // tmp10 - tmp12
1119  psllw_i2r(2, mm4); // shift tmp10
1120 
1121  movq_m2r(RTjpeg_C2mC6, mm0); // load C2mC6
1122  psllw_i2r(2, mm1); // shift (tmp10-tmp12)
1123 
1124  pmulhw_m2r(RTjpeg_C6, mm1); // z5
1125  psllw_i2r(2, mm5); // prepare for multiply
1126 
1127  pmulhw_r2r(mm0, mm4); // multiply by converted real
1128 
1129  /* stage 5 */
1130 
1131  pmulhw_m2r(RTjpeg_C4, mm5); // z3
1132  psllw_i2r(2, mm2); // prepare for multiply
1133 
1134  pmulhw_m2r(RTjpeg_C2pC6, mm2); // multiply
1135  movq_r2r(mm3, mm0); // copy tmp7
1136 
1137  movq_m2r(*(dataptr+9), mm7); // m03:m02|m01:m00 - first line (line 4)and copy into mm7
1138  paddw_r2r(mm1, mm4); // z2
1139 
1140  paddw_r2r(mm5, mm0); // z11
1141  psubw_r2r(mm5, mm3); // z13
1142 
1143  /* stage 6 */
1144 
1145  movq_r2r(mm3, mm5); // copy z13
1146  paddw_r2r(mm1, mm2); // z4
1147 
1148  movq_r2r(mm0, mm6); // copy z11
1149  psubw_r2r(mm4, mm5); // y3
1150 
1151  paddw_r2r(mm2, mm6); // y1
1152  paddw_r2r(mm4, mm3); // y5
1153 
1154  movq_r2m(mm5, *(dataptr+7)); //save y3
1155 
1156  movq_r2m(mm6, *(dataptr+3)); //save y1
1157  psubw_r2r(mm2, mm0); // y7
1158 
1159 /************************************************************************************************
1160  Start of Transpose
1161 ************************************************************************************************/
1162 
1163  movq_m2r(*(dataptr+13), mm6); // m23:m22|m21:m20 - third line (line 6)and copy into m2
1164  movq_r2r(mm7, mm5); // copy first line
1165 
1166  punpcklwd_r2r(mm3, mm7); // m11:m01|m10:m00 - interleave first and second lines
1167  movq_r2r(mm6, mm2); // copy third line
1168 
1169  punpcklwd_r2r(mm0, mm6); // m31:m21|m30:m20 - interleave third and fourth lines
1170  movq_r2r(mm7, mm1); // copy first intermediate result
1171 
1172  punpckldq_r2r(mm6, mm7); // m30:m20|m10:m00 - interleave to produce result 1
1173 
1174  punpckhdq_r2r(mm6, mm1); // m31:m21|m11:m01 - interleave to produce result 2
1175 
1176  movq_r2m(mm7, *(dataptr+9)); // write result 1
1177  punpckhwd_r2r(mm3, mm5); // m13:m03|m12:m02 - interleave first and second lines
1178 
1179  movq_r2m(mm1, *(dataptr+11)); // write result 2
1180  punpckhwd_r2r(mm0, mm2); // m33:m23|m32:m22 - interleave third and fourth lines
1181 
1182  movq_r2r(mm5, mm1); // copy first intermediate result
1183  punpckldq_r2r(mm2, mm5); // m32:m22|m12:m02 - interleave to produce result 3
1184 
1185  movq_m2r(*(dataptr+1), mm0); // m03:m02|m01:m00 - first line, 4x4
1186  punpckhdq_r2r(mm2, mm1); // m33:m23|m13:m03 - interleave to produce result 4
1187 
1188  movq_r2m(mm5, *(dataptr+13)); // write result 3
1189 
1190  /****** last 4x4 done */
1191 
1192  movq_r2m(mm1, *(dataptr+15)); // write result 4, last 4x4
1193 
1194  movq_m2r(*(dataptr+5), mm2); // m23:m22|m21:m20 - third line
1195  movq_r2r(mm0, mm6); // copy first line
1196 
1197  punpcklwd_m2r(*(dataptr+3), mm0); // m11:m01|m10:m00 - interleave first and second lines
1198  movq_r2r(mm2, mm7); // copy third line
1199 
1200  punpcklwd_m2r(*(dataptr+7), mm2); // m31:m21|m30:m20 - interleave third and fourth lines
1201  movq_r2r(mm0, mm4); // copy first intermediate result
1202 
1203 
1204 
1205  movq_m2r(*(dataptr+8), mm1); // n03:n02|n01:n00 - first line
1206  punpckldq_r2r(mm2, mm0); // m30:m20|m10:m00 - interleave to produce first result
1207 
1208  movq_m2r(*(dataptr+12), mm3); // n23:n22|n21:n20 - third line
1209  punpckhdq_r2r(mm2, mm4); // m31:m21|m11:m01 - interleave to produce second result
1210 
1211  punpckhwd_m2r(*(dataptr+3), mm6); // m13:m03|m12:m02 - interleave first and second lines
1212  movq_r2r(mm1, mm2); // copy first line
1213 
1214  punpckhwd_m2r(*(dataptr+7), mm7); // m33:m23|m32:m22 - interleave third and fourth lines
1215  movq_r2r(mm6, mm5); // copy first intermediate result
1216 
1217  movq_r2m(mm0, *(dataptr+8)); // write result 1
1218  punpckhdq_r2r(mm7, mm5); // m33:m23|m13:m03 - produce third result
1219 
1220  punpcklwd_m2r(*(dataptr+10), mm1); // n11:n01|n10:n00 - interleave first and second lines
1221  movq_r2r(mm3, mm0); // copy third line
1222 
1223  punpckhwd_m2r(*(dataptr+10), mm2); // n13:n03|n12:n02 - interleave first and second lines
1224 
1225  movq_r2m(mm4, *(dataptr+10)); // write result 2 out
1226  punpckldq_r2r(mm7, mm6); // m32:m22|m12:m02 - produce fourth result
1227 
1228  punpcklwd_m2r(*(dataptr+14), mm3); // n33:n23|n32:n22 - interleave third and fourth lines
1229  movq_r2r(mm1, mm4); // copy second intermediate result
1230 
1231  movq_r2m(mm6, *(dataptr+12)); // write result 3 out
1232  punpckldq_r2r(mm3, mm1); //
1233 
1234  punpckhwd_m2r(*(dataptr+14), mm0); // n33:n23|n32:n22 - interleave third and fourth lines
1235  movq_r2r(mm2, mm6); // copy second intermediate result
1236 
1237  movq_r2m(mm5, *(dataptr+14)); // write result 4 out
1238  punpckhdq_r2r(mm3, mm4); // n31:n21|n11:n01- produce second result
1239 
1240  movq_r2m(mm1, *(dataptr+1)); // write result 5 out - (first result for other 4 x 4 block)
1241  punpckldq_r2r(mm0, mm2); // n32:n22|n12:n02- produce third result
1242 
1243  movq_r2m(mm4, *(dataptr+3)); // write result 6 out
1244  punpckhdq_r2r(mm0, mm6); // n33:n23|n13:n03 - produce fourth result
1245 
1246  movq_r2m(mm2, *(dataptr+5)); // write result 7 out
1247 
1248  movq_m2r(*dataptr, mm0); // m03:m02|m01:m00 - first line, first 4x4
1249 
1250  movq_r2m(mm6, *(dataptr+7)); // write result 8 out
1251 
1252 // Do first 4x4 quadrant, which is used in the beginning of the DCT:
1253 
1254  movq_m2r(*(dataptr+4), mm7); // m23:m22|m21:m20 - third line
1255  movq_r2r(mm0, mm2); // copy first line
1256 
1257  punpcklwd_m2r(*(dataptr+2), mm0); // m11:m01|m10:m00 - interleave first and second lines
1258  movq_r2r(mm7, mm4); // copy third line
1259 
1260  punpcklwd_m2r(*(dataptr+6), mm7); // m31:m21|m30:m20 - interleave third and fourth lines
1261  movq_r2r(mm0, mm1); // copy first intermediate result
1262 
1263  movq_m2r(*(dataptr+2), mm6); // m13:m12|m11:m10 - second line
1264  punpckldq_r2r(mm7, mm0); // m30:m20|m10:m00 - interleave to produce result 1
1265 
1266  movq_m2r(*(dataptr+6), mm5); // m33:m32|m31:m30 - fourth line
1267  punpckhdq_r2r(mm7, mm1); // m31:m21|m11:m01 - interleave to produce result 2
1268 
1269  movq_r2r(mm0, mm7); // write result 1
1270  punpckhwd_r2r(mm6, mm2); // m13:m03|m12:m02 - interleave first and second lines
1271 
1272  psubw_m2r(*(dataptr+14), mm7); // tmp07=x0-x7 /* Stage 1 */
1273  movq_r2r(mm1, mm6); // write result 2
1274 
1275  paddw_m2r(*(dataptr+14), mm0); // tmp00=x0+x7 /* Stage 1 */
1276  punpckhwd_r2r(mm5, mm4); // m33:m23|m32:m22 - interleave third and fourth lines
1277 
1278  paddw_m2r(*(dataptr+12), mm1); // tmp01=x1+x6 /* Stage 1 */
1279  movq_r2r(mm2, mm3); // copy first intermediate result
1280 
1281  psubw_m2r(*(dataptr+12), mm6); // tmp06=x1-x6 /* Stage 1 */
1282  punpckldq_r2r(mm4, mm2); // m32:m22|m12:m02 - interleave to produce result 3
1283 
1284  movq_r2m(mm7, tmp7); // save tmp07
1285  movq_r2r(mm2, mm5); // write result 3
1286 
1287  movq_r2m(mm6, tmp6); // save tmp06
1288 
1289  punpckhdq_r2r(mm4, mm3); // m33:m23|m13:m03 - interleave to produce result 4
1290 
1291  paddw_m2r(*(dataptr+10), mm2); // tmp02=x2+x5 /* stage 1 */
1292  movq_r2r(mm3, mm4); // write result 4
1293 
1294 /************************************************************************************************
1295  End of Transpose 2
1296 ************************************************************************************************/
1297 
1298  paddw_m2r(*(dataptr+8), mm3); // tmp03=x3+x4 /* stage 1*/
1299  movq_r2r(mm0, mm7);
1300 
1301  psubw_m2r(*(dataptr+8), mm4); // tmp04=x3-x4 /* stage 1*/
1302  movq_r2r(mm1, mm6);
1303 
1304  paddw_r2r(mm3, mm0); // tmp10 = tmp00 + tmp03 /* even 2 */
1305  psubw_r2r(mm3, mm7); // tmp13 = tmp00 - tmp03 /* even 2 */
1306 
1307  psubw_r2r(mm2, mm6); // tmp12 = tmp01 - tmp02 /* even 2 */
1308  paddw_r2r(mm2, mm1); // tmp11 = tmp01 + tmp02 /* even 2 */
1309 
1310  psubw_m2r(*(dataptr+10), mm5); // tmp05=x2-x5 /* stage 1*/
1311  paddw_r2r(mm7, mm6); // tmp12 + tmp13
1312 
1313  /* stage 3 */
1314 
1315  movq_m2r(tmp6, mm2);
1316  movq_r2r(mm0, mm3);
1317 
1318  psllw_i2r(2, mm6); // m8 * 2^2
1319  paddw_r2r(mm1, mm0);
1320 
1321  pmulhw_m2r(RTjpeg_C4, mm6); // z1
1322  psubw_r2r(mm1, mm3);
1323 
1324  movq_r2m(mm0, *dataptr);
1325  movq_r2r(mm7, mm0);
1326 
1327  /* Odd part */
1328  movq_r2m(mm3, *(dataptr+8));
1329  paddw_r2r(mm5, mm4); // tmp10
1330 
1331  movq_m2r(tmp7, mm3);
1332  paddw_r2r(mm6, mm0); // tmp32
1333 
1334  paddw_r2r(mm2, mm5); // tmp11
1335  psubw_r2r(mm6, mm7); // tmp33
1336 
1337  movq_r2m(mm0, *(dataptr+4));
1338  paddw_r2r(mm3, mm2); // tmp12
1339 
1340  /* stage 4 */
1341  movq_r2m(mm7, *(dataptr+12));
1342  movq_r2r(mm4, mm1); // copy of tmp10
1343 
1344  psubw_r2r(mm2, mm1); // tmp10 - tmp12
1345  psllw_i2r(2, mm4); // m8 * 2^2
1346 
1347  movq_m2r(RTjpeg_C2mC6, mm0);
1348  psllw_i2r(2, mm1);
1349 
1350  pmulhw_m2r(RTjpeg_C6, mm1); // z5
1351  psllw_i2r(2, mm2);
1352 
1353  pmulhw_r2r(mm0, mm4); // z5
1354 
1355  /* stage 5 */
1356 
1357  pmulhw_m2r(RTjpeg_C2pC6, mm2);
1358  psllw_i2r(2, mm5);
1359 
1360  pmulhw_m2r(RTjpeg_C4, mm5); // z3
1361  movq_r2r(mm3, mm0); // copy tmp7
1362 
1363  movq_m2r(*(dataptr+1), mm7);
1364  paddw_r2r(mm1, mm4); // z2
1365 
1366  paddw_r2r(mm1, mm2); // z4
1367 
1368  paddw_r2r(mm5, mm0); // z11
1369  psubw_r2r(mm5, mm3); // z13
1370 
1371  /* stage 6 */
1372 
1373  movq_r2r(mm3, mm5); // copy z13
1374  psubw_r2r(mm4, mm3); // y3=z13 - z2
1375 
1376  paddw_r2r(mm4, mm5); // y5=z13 + z2
1377  movq_r2r(mm0, mm6); // copy z11
1378 
1379  movq_r2m(mm3, *(dataptr+6)); //save y3
1380  psubw_r2r(mm2, mm0); // y7=z11 - z4
1381 
1382  movq_r2m(mm5, *(dataptr+10)); //save y5
1383  paddw_r2r(mm2, mm6); // y1=z11 + z4
1384 
1385  movq_r2m(mm0, *(dataptr+14)); //save y7
1386 
1387  /************************************************
1388  * End of 1st 4 rows
1389  ************************************************/
1390 
1391  movq_m2r(*(dataptr+3), mm1); // load x1 /* stage 1 */
1392  movq_r2r(mm7, mm0); // copy x0
1393 
1394  movq_r2m(mm6, *(dataptr+2)); //save y1
1395 
1396  movq_m2r(*(dataptr+5), mm2); // load x2 /* stage 1 */
1397  movq_r2r(mm1, mm6); // copy x1
1398 
1399  paddw_m2r(*(dataptr+15), mm0); // tmp00 = x0 + x7
1400 
1401  movq_m2r(*(dataptr+7), mm3); // load x3 /* stage 1 */
1402  movq_r2r(mm2, mm5); // copy x2
1403 
1404  psubw_m2r(*(dataptr+15), mm7); // tmp07 = x0 - x7
1405  movq_r2r(mm3, mm4); // copy x3
1406 
1407  paddw_m2r(*(dataptr+13), mm1); // tmp01 = x1 + x6
1408 
1409  movq_r2m(mm7, tmp7); // save tmp07
1410  movq_r2r(mm0, mm7); // copy tmp00
1411 
1412  psubw_m2r(*(dataptr+13), mm6); // tmp06 = x1 - x6
1413 
1414  /* stage 2, Even Part */
1415 
1416  paddw_m2r(*(dataptr+9), mm3); // tmp03 = x3 + x4
1417 
1418  movq_r2m(mm6, tmp6); // save tmp07
1419  movq_r2r(mm1, mm6); // copy tmp01
1420 
1421  paddw_m2r(*(dataptr+11), mm2); // tmp02 = x2 + x5
1422  paddw_r2r(mm3, mm0); // tmp10 = tmp00 + tmp03
1423 
1424  psubw_r2r(mm3, mm7); // tmp13 = tmp00 - tmp03
1425 
1426  psubw_m2r(*(dataptr+9), mm4); // tmp04 = x3 - x4
1427  psubw_r2r(mm2, mm6); // tmp12 = tmp01 - tmp02
1428 
1429  paddw_r2r(mm2, mm1); // tmp11 = tmp01 + tmp02
1430 
1431  psubw_m2r(*(dataptr+11), mm5); // tmp05 = x2 - x5
1432  paddw_r2r(mm7, mm6); // tmp12 + tmp13
1433 
1434  /* stage 3, Even and stage 4 & 5 even */
1435 
1436  movq_m2r(tmp6, mm2); // load tmp6
1437  movq_r2r(mm0, mm3); // copy tmp10
1438 
1439  psllw_i2r(2, mm6); // shift z1
1440  paddw_r2r(mm1, mm0); // y0=tmp10 + tmp11
1441 
1442  pmulhw_m2r(RTjpeg_C4, mm6); // z1
1443  psubw_r2r(mm1, mm3); // y4=tmp10 - tmp11
1444 
1445  movq_r2m(mm0, *(dataptr+1)); //save y0
1446  movq_r2r(mm7, mm0); // copy tmp13
1447 
1448  /* odd part */
1449 
1450  movq_r2m(mm3, *(dataptr+9)); //save y4
1451  paddw_r2r(mm5, mm4); // tmp10 = tmp4 + tmp5
1452 
1453  movq_m2r(tmp7, mm3); // load tmp7
1454  paddw_r2r(mm6, mm0); // tmp32 = tmp13 + z1
1455 
1456  paddw_r2r(mm2, mm5); // tmp11 = tmp5 + tmp6
1457  psubw_r2r(mm6, mm7); // tmp33 = tmp13 - z1
1458 
1459  movq_r2m(mm0, *(dataptr+5)); //save y2
1460  paddw_r2r(mm3, mm2); // tmp12 = tmp6 + tmp7
1461 
1462  /* stage 4 */
1463 
1464  movq_r2m(mm7, *(dataptr+13)); //save y6
1465  movq_r2r(mm4, mm1); // copy tmp10
1466 
1467  psubw_r2r(mm2, mm1); // tmp10 - tmp12
1468  psllw_i2r(2, mm4); // shift tmp10
1469 
1470  movq_m2r(RTjpeg_C2mC6, mm0); // load C2mC6
1471  psllw_i2r(2, mm1); // shift (tmp10-tmp12)
1472 
1473  pmulhw_m2r(RTjpeg_C6, mm1); // z5
1474  psllw_i2r(2, mm5); // prepare for multiply
1475 
1476  pmulhw_r2r(mm0, mm4); // multiply by converted real
1477 
1478  /* stage 5 */
1479 
1480  pmulhw_m2r(RTjpeg_C4, mm5); // z3
1481  psllw_i2r(2, mm2); // prepare for multiply
1482 
1483  pmulhw_m2r(RTjpeg_C2pC6, mm2); // multiply
1484  movq_r2r(mm3, mm0); // copy tmp7
1485 
1486  movq_m2r(*(dataptr+9), mm7); // m03:m02|m01:m00 - first line (line 4)and copy into mm7
1487  paddw_r2r(mm1, mm4); // z2
1488 
1489  paddw_r2r(mm5, mm0); // z11
1490  psubw_r2r(mm5, mm3); // z13
1491 
1492  /* stage 6 */
1493 
1494  movq_r2r(mm3, mm5); // copy z13
1495  paddw_r2r(mm1, mm2); // z4
1496 
1497  movq_r2r(mm0, mm6); // copy z11
1498  psubw_r2r(mm4, mm5); // y3
1499 
1500  paddw_r2r(mm2, mm6); // y1
1501  paddw_r2r(mm4, mm3); // y5
1502 
1503  movq_r2m(mm5, *(dataptr+7)); //save y3
1504  psubw_r2r(mm2, mm0); // yŤ=z11 - z4
1505 
1506  movq_r2m(mm3, *(dataptr+11)); //save y5
1507 
1508  movq_r2m(mm6, *(dataptr+3)); //save y1
1509 
1510  movq_r2m(mm0, *(dataptr+15)); //save y7
1511 
1512 
1513 #endif
1514 }
1515 
1516 #define FIX_1_082392200 ((int32_t) 277) /* FIX(1.082392200) */
1517 #define FIX_1_414213562 ((int32_t) 362) /* FIX(1.414213562) */
1518 #define FIX_1_847759065 ((int32_t) 473) /* FIX(1.847759065) */
1519 #define FIX_2_613125930 ((int32_t) 669) /* FIX(2.613125930) */
1520 
1521 #define DESCALE(x) (int16_t)( ((x)+4) >> 3)
1522 
1523 /* clip yuv to 16..235 (should be 16..240 for cr/cb but ... */
1524 
1525 #define RL(x) ((x)>235) ? 235 : (((x)<16) ? 16 : (x))
1526 #define MULTIPLY(var,const) (((int32_t) ((var) * (const)) + 128)>>8)
1527 
1529 {
1530  int i;
1531 
1532  for( i = 0; i < 64; i++)
1533  {
1534  liqt[i] = ((uint64_t)liqt[i] * RTjpeg_aan_tab[i]) >> 32;
1535  ciqt[i] = ((uint64_t)ciqt[i] * RTjpeg_aan_tab[i]) >> 32;
1536  }
1537 }
1538 
1539 void RTjpeg::Idct(uint8_t *odata, int16_t *data, int rskip)
1540 {
1541 #ifdef MMX
1542 
1543 static mmx_t fix_141; fix_141.q = 0x5a825a825a825a82LL;
1544 static mmx_t fix_184n261; fix_184n261.q = 0xcf04cf04cf04cf04LL;
1545 static mmx_t fix_184; fix_184.q = 0x7641764176417641LL;
1546 static mmx_t fix_n184; fix_n184.q = 0x896f896f896f896fLL;
1547 static mmx_t fix_108n184; fix_108n184.q = 0xcf04cf04cf04cf04LL;
1548 
1549  mmx_t *wsptr = (mmx_t *)ws;
1550  mmx_t *dataptr = (mmx_t *)odata;
1551  mmx_t *idata = (mmx_t *)data;
1552 
1553  rskip = rskip>>3;
1554 /*
1555  * Perform inverse DCT on one block of coefficients.
1556  */
1557 
1558  /* Odd part */
1559 
1560  movq_m2r(*(idata+10), mm1); // load idata[DCTSIZE*5]
1561 
1562  movq_m2r(*(idata+6), mm0); // load idata[DCTSIZE*3]
1563 
1564  movq_m2r(*(idata+2), mm3); // load idata[DCTSIZE*1]
1565 
1566  movq_r2r(mm1, mm2); // copy tmp6 /* phase 6 */
1567 
1568  movq_m2r(*(idata+14), mm4); // load idata[DCTSIZE*7]
1569 
1570  paddw_r2r(mm0, mm1); // z13 = tmp6 + tmp5;
1571 
1572  psubw_r2r(mm0, mm2); // z10 = tmp6 - tmp5
1573 
1574  psllw_i2r(2, mm2); // shift z10
1575  movq_r2r(mm2, mm0); // copy z10
1576 
1577  pmulhw_m2r(fix_184n261, mm2); // MULTIPLY( z12, FIX_1_847759065); /* 2*c2 */
1578  movq_r2r(mm3, mm5); // copy tmp4
1579 
1580  pmulhw_m2r(fix_n184, mm0); // MULTIPLY(z10, -FIX_1_847759065); /* 2*c2 */
1581  paddw_r2r(mm4, mm3); // z11 = tmp4 + tmp7;
1582 
1583  movq_r2r(mm3, mm6); // copy z11 /* phase 5 */
1584  psubw_r2r(mm4, mm5); // z12 = tmp4 - tmp7;
1585 
1586  psubw_r2r(mm1, mm6); // z11-z13
1587  psllw_i2r(2, mm5); // shift z12
1588 
1589  movq_m2r(*(idata+12), mm4); // load idata[DCTSIZE*6], even part
1590  movq_r2r(mm5, mm7); // copy z12
1591 
1592  pmulhw_m2r(fix_108n184, mm5); // MULT(z12, (FIX_1_08-FIX_1_84)) //- z5; /* 2*(c2-c6) */ even part
1593  paddw_r2r(mm1, mm3); // tmp7 = z11 + z13;
1594 
1595  //ok
1596 
1597  /* Even part */
1598  pmulhw_m2r(fix_184, mm7); // MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) //+ z5; /* -2*(c2+c6) */
1599  psllw_i2r(2, mm6);
1600 
1601  movq_m2r(*(idata+4), mm1); // load idata[DCTSIZE*2]
1602 
1603  paddw_r2r(mm5, mm0); // tmp10
1604 
1605  paddw_r2r(mm7, mm2); // tmp12
1606 
1607  pmulhw_m2r(fix_141, mm6); // tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
1608  psubw_r2r(mm3, mm2); // tmp6 = tmp12 - tmp7
1609 
1610  movq_r2r(mm1, mm5); // copy tmp1
1611  paddw_r2r(mm4, mm1); // tmp13= tmp1 + tmp3; /* phases 5-3 */
1612 
1613  psubw_r2r(mm4, mm5); // tmp1-tmp3
1614  psubw_r2r(mm2, mm6); // tmp5 = tmp11 - tmp6;
1615 
1616  movq_r2m(mm1, *(wsptr)); // save tmp13 in workspace
1617  psllw_i2r(2, mm5); // shift tmp1-tmp3
1618 
1619  movq_m2r(*(idata), mm7); // load idata[DCTSIZE*0]
1620 
1621  pmulhw_m2r(fix_141, mm5); // MULTIPLY(tmp1 - tmp3, FIX_1_414213562)
1622  paddw_r2r(mm6, mm0); // tmp4 = tmp10 + tmp5;
1623 
1624  movq_m2r(*(idata+8), mm4); // load idata[DCTSIZE*4]
1625 
1626  psubw_r2r(mm1, mm5); // tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
1627 
1628  movq_r2m(mm0, *(wsptr+4)); // save tmp4 in workspace
1629  movq_r2r(mm7, mm1); // copy tmp0 /* phase 3 */
1630 
1631  movq_r2m(mm5, *(wsptr+2)); // save tmp12 in workspace
1632  psubw_r2r(mm4, mm1); // tmp11 = tmp0 - tmp2;
1633 
1634  paddw_r2r(mm4, mm7); // tmp10 = tmp0 + tmp2;
1635  movq_r2r(mm1, mm5); // copy tmp11
1636 
1637  paddw_m2r(*(wsptr+2), mm1); // tmp1 = tmp11 + tmp12;
1638  movq_r2r(mm7, mm4); // copy tmp10 /* phase 2 */
1639 
1640  paddw_m2r(*(wsptr), mm7); // tmp0 = tmp10 + tmp13;
1641 
1642  psubw_m2r(*(wsptr), mm4); // tmp3 = tmp10 - tmp13;
1643  movq_r2r(mm7, mm0); // copy tmp0
1644 
1645  psubw_m2r(*(wsptr+2), mm5); // tmp2 = tmp11 - tmp12;
1646  paddw_r2r(mm3, mm7); // wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
1647 
1648  psubw_r2r(mm3, mm0); // wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
1649 
1650  movq_r2m(mm7, *(wsptr)); // wsptr[DCTSIZE*0]
1651  movq_r2r(mm1, mm3); // copy tmp1
1652 
1653  movq_r2m(mm0, *(wsptr+14)); // wsptr[DCTSIZE*7]
1654  paddw_r2r(mm2, mm1); // wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
1655 
1656  psubw_r2r(mm2, mm3); // wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
1657 
1658  movq_r2m(mm1, *(wsptr+2)); // wsptr[DCTSIZE*1]
1659  movq_r2r(mm4, mm1); // copy tmp3
1660 
1661  movq_r2m(mm3, *(wsptr+12)); // wsptr[DCTSIZE*6]
1662 
1663  paddw_m2r(*(wsptr+4), mm4); // wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
1664 
1665  psubw_m2r(*(wsptr+4), mm1); // wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
1666 
1667  movq_r2m(mm4, *(wsptr+8));
1668  movq_r2r(mm5, mm7); // copy tmp2
1669 
1670  paddw_r2r(mm6, mm5); // wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5)
1671 
1672  movq_r2m(mm1, *(wsptr+6));
1673  psubw_r2r(mm6, mm7); // wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
1674 
1675  movq_r2m(mm5, *(wsptr+4));
1676 
1677  movq_r2m(mm7, *(wsptr+10));
1678 
1679  //ok
1680 
1681 
1682 /*****************************************************************/
1683 
1684  idata++;
1685  wsptr++;
1686 
1687 /*****************************************************************/
1688 
1689  movq_m2r(*(idata+10), mm1); // load idata[DCTSIZE*5]
1690 
1691  movq_m2r(*(idata+6), mm0); // load idata[DCTSIZE*3]
1692 
1693  movq_m2r(*(idata+2), mm3); // load idata[DCTSIZE*1]
1694  movq_r2r(mm1, mm2); // copy tmp6 /* phase 6 */
1695 
1696  movq_m2r(*(idata+14), mm4); // load idata[DCTSIZE*7]
1697  paddw_r2r(mm0, mm1); // z13 = tmp6 + tmp5;
1698 
1699  psubw_r2r(mm0, mm2); // z10 = tmp6 - tmp5
1700 
1701  psllw_i2r(2, mm2); // shift z10
1702  movq_r2r(mm2, mm0); // copy z10
1703 
1704  pmulhw_m2r(fix_184n261, mm2); // MULTIPLY( z12, FIX_1_847759065); /* 2*c2 */
1705  movq_r2r(mm3, mm5); // copy tmp4
1706 
1707  pmulhw_m2r(fix_n184, mm0); // MULTIPLY(z10, -FIX_1_847759065); /* 2*c2 */
1708  paddw_r2r(mm4, mm3); // z11 = tmp4 + tmp7;
1709 
1710  movq_r2r(mm3, mm6); // copy z11 /* phase 5 */
1711  psubw_r2r(mm4, mm5); // z12 = tmp4 - tmp7;
1712 
1713  psubw_r2r(mm1, mm6); // z11-z13
1714  psllw_i2r(2, mm5); // shift z12
1715 
1716  movq_m2r(*(idata+12), mm4); // load idata[DCTSIZE*6], even part
1717  movq_r2r(mm5, mm7); // copy z12
1718 
1719  pmulhw_m2r(fix_108n184, mm5); // MULT(z12, (FIX_1_08-FIX_1_84)) //- z5; /* 2*(c2-c6) */ even part
1720  paddw_r2r(mm1, mm3); // tmp7 = z11 + z13;
1721 
1722  //ok
1723 
1724  /* Even part */
1725  pmulhw_m2r(fix_184, mm7); // MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) //+ z5; /* -2*(c2+c6) */
1726  psllw_i2r(2, mm6);
1727 
1728  movq_m2r(*(idata+4), mm1); // load idata[DCTSIZE*2]
1729 
1730  paddw_r2r(mm5, mm0); // tmp10
1731 
1732  paddw_r2r(mm7, mm2); // tmp12
1733 
1734  pmulhw_m2r(fix_141, mm6); // tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
1735  psubw_r2r(mm3, mm2); // tmp6 = tmp12 - tmp7
1736 
1737  movq_r2r(mm1, mm5); // copy tmp1
1738  paddw_r2r(mm4, mm1); // tmp13= tmp1 + tmp3; /* phases 5-3 */
1739 
1740  psubw_r2r(mm4, mm5); // tmp1-tmp3
1741  psubw_r2r(mm2, mm6); // tmp5 = tmp11 - tmp6;
1742 
1743  movq_r2m(mm1, *(wsptr)); // save tmp13 in workspace
1744  psllw_i2r(2, mm5); // shift tmp1-tmp3
1745 
1746  movq_m2r(*(idata), mm7); // load idata[DCTSIZE*0]
1747  paddw_r2r(mm6, mm0); // tmp4 = tmp10 + tmp5;
1748 
1749  pmulhw_m2r(fix_141, mm5); // MULTIPLY(tmp1 - tmp3, FIX_1_414213562)
1750 
1751  movq_m2r(*(idata+8), mm4); // load idata[DCTSIZE*4]
1752 
1753  psubw_r2r(mm1, mm5); // tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
1754 
1755  movq_r2m(mm0, *(wsptr+4)); // save tmp4 in workspace
1756  movq_r2r(mm7, mm1); // copy tmp0 /* phase 3 */
1757 
1758  movq_r2m(mm5, *(wsptr+2)); // save tmp12 in workspace
1759  psubw_r2r(mm4, mm1); // tmp11 = tmp0 - tmp2;
1760 
1761  paddw_r2r(mm4, mm7); // tmp10 = tmp0 + tmp2;
1762  movq_r2r(mm1, mm5); // copy tmp11
1763 
1764  paddw_m2r(*(wsptr+2), mm1); // tmp1 = tmp11 + tmp12;
1765  movq_r2r(mm7, mm4); // copy tmp10 /* phase 2 */
1766 
1767  paddw_m2r(*(wsptr), mm7); // tmp0 = tmp10 + tmp13;
1768 
1769  psubw_m2r(*(wsptr), mm4); // tmp3 = tmp10 - tmp13;
1770  movq_r2r(mm7, mm0); // copy tmp0
1771 
1772  psubw_m2r(*(wsptr+2), mm5); // tmp2 = tmp11 - tmp12;
1773  paddw_r2r(mm3, mm7); // wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
1774 
1775  psubw_r2r(mm3, mm0); // wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
1776 
1777  movq_r2m(mm7, *(wsptr)); // wsptr[DCTSIZE*0]
1778  movq_r2r(mm1, mm3); // copy tmp1
1779 
1780  movq_r2m(mm0, *(wsptr+14)); // wsptr[DCTSIZE*7]
1781  paddw_r2r(mm2, mm1); // wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
1782 
1783  psubw_r2r(mm2, mm3); // wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
1784 
1785  movq_r2m(mm1, *(wsptr+2)); // wsptr[DCTSIZE*1]
1786  movq_r2r(mm4, mm1); // copy tmp3
1787 
1788  movq_r2m(mm3, *(wsptr+12)); // wsptr[DCTSIZE*6]
1789 
1790  paddw_m2r(*(wsptr+4), mm4); // wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
1791 
1792  psubw_m2r(*(wsptr+4), mm1); // wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
1793 
1794  movq_r2m(mm4, *(wsptr+8));
1795  movq_r2r(mm5, mm7); // copy tmp2
1796 
1797  paddw_r2r(mm6, mm5); // wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5)
1798 
1799  movq_r2m(mm1, *(wsptr+6));
1800  psubw_r2r(mm6, mm7); // wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
1801 
1802  movq_r2m(mm5, *(wsptr+4));
1803 
1804  movq_r2m(mm7, *(wsptr+10));
1805 
1806 /*****************************************************************/
1807 
1808  /* Pass 2: process rows from work array, store into output array. */
1809  /* Note that we must descale the results by a factor of 8 == 2**3, */
1810  /* and also undo the PASS1_BITS scaling. */
1811 
1812 /*****************************************************************/
1813  /* Even part */
1814 
1815  wsptr--;
1816 
1817 // tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
1818 // tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
1819 // tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
1820 // tmp14 = ((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6]);
1821  movq_m2r(*(wsptr), mm0); // wsptr[0,0],[0,1],[0,2],[0,3]
1822 
1823  movq_m2r(*(wsptr+1), mm1); // wsptr[0,4],[0,5],[0,6],[0,7]
1824  movq_r2r(mm0, mm2);
1825 
1826  movq_m2r(*(wsptr+2), mm3); // wsptr[1,0],[1,1],[1,2],[1,3]
1827  paddw_r2r(mm1, mm0); // wsptr[0,tmp10],[xxx],[0,tmp13],[xxx]
1828 
1829  movq_m2r(*(wsptr+3), mm4); // wsptr[1,4],[1,5],[1,6],[1,7]
1830  psubw_r2r(mm1, mm2); // wsptr[0,tmp11],[xxx],[0,tmp14],[xxx]
1831 
1832  movq_r2r(mm0, mm6);
1833  movq_r2r(mm3, mm5);
1834 
1835  paddw_r2r(mm4, mm3); // wsptr[1,tmp10],[xxx],[1,tmp13],[xxx]
1836  movq_r2r(mm2, mm1);
1837 
1838  psubw_r2r(mm4, mm5); // wsptr[1,tmp11],[xxx],[1,tmp14],[xxx]
1839  punpcklwd_r2r(mm3, mm0); // wsptr[0,tmp10],[1,tmp10],[xxx],[xxx]
1840 
1841  movq_m2r(*(wsptr+7), mm7); // wsptr[3,4],[3,5],[3,6],[3,7]
1842  punpckhwd_r2r(mm3, mm6); // wsptr[0,tmp13],[1,tmp13],[xxx],[xxx]
1843 
1844  movq_m2r(*(wsptr+4), mm3); // wsptr[2,0],[2,1],[2,2],[2,3]
1845  punpckldq_r2r(mm6, mm0); // wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
1846 
1847  punpcklwd_r2r(mm5, mm1); // wsptr[0,tmp11],[1,tmp11],[xxx],[xxx]
1848  movq_r2r(mm3, mm4);
1849 
1850  movq_m2r(*(wsptr+6), mm6); // wsptr[3,0],[3,1],[3,2],[3,3]
1851  punpckhwd_r2r(mm5, mm2); // wsptr[0,tmp14],[1,tmp14],[xxx],[xxx]
1852 
1853  movq_m2r(*(wsptr+5), mm5); // wsptr[2,4],[2,5],[2,6],[2,7]
1854  punpckldq_r2r(mm2, mm1); // wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
1855 
1856 
1857  paddw_r2r(mm5, mm3); // wsptr[2,tmp10],[xxx],[2,tmp13],[xxx]
1858  movq_r2r(mm6, mm2);
1859 
1860  psubw_r2r(mm5, mm4); // wsptr[2,tmp11],[xxx],[2,tmp14],[xxx]
1861  paddw_r2r(mm7, mm6); // wsptr[3,tmp10],[xxx],[3,tmp13],[xxx]
1862 
1863  movq_r2r(mm3, mm5);
1864  punpcklwd_r2r(mm6, mm3); // wsptr[2,tmp10],[3,tmp10],[xxx],[xxx]
1865 
1866  psubw_r2r(mm7, mm2); // wsptr[3,tmp11],[xxx],[3,tmp14],[xxx]
1867  punpckhwd_r2r(mm6, mm5); // wsptr[2,tmp13],[3,tmp13],[xxx],[xxx]
1868 
1869  movq_r2r(mm4, mm7);
1870  punpckldq_r2r(mm5, mm3); // wsptr[2,tmp10],[3,tmp10],[2,tmp13],[3,tmp13]
1871 
1872  punpcklwd_r2r(mm2, mm4); // wsptr[2,tmp11],[3,tmp11],[xxx],[xxx]
1873 
1874  punpckhwd_r2r(mm2, mm7); // wsptr[2,tmp14],[3,tmp14],[xxx],[xxx]
1875 
1876  punpckldq_r2r(mm7, mm4); // wsptr[2,tmp11],[3,tmp11],[2,tmp14],[3,tmp14]
1877  movq_r2r(mm1, mm6);
1878 
1879  //ok
1880 
1881 // mm0 = ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
1882 // mm1 = ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
1883 
1884 
1885  movq_r2r(mm0, mm2);
1886  punpckhdq_r2r(mm4, mm6); // wsptr[0,tmp14],[1,tmp14],[2,tmp14],[3,tmp14]
1887 
1888  punpckldq_r2r(mm4, mm1); // wsptr[0,tmp11],[1,tmp11],[2,tmp11],[3,tmp11]
1889  psllw_i2r(2, mm6);
1890 
1891  pmulhw_m2r(fix_141, mm6);
1892  punpckldq_r2r(mm3, mm0); // wsptr[0,tmp10],[1,tmp10],[2,tmp10],[3,tmp10]
1893 
1894  punpckhdq_r2r(mm3, mm2); // wsptr[0,tmp13],[1,tmp13],[2,tmp13],[3,tmp13]
1895  movq_r2r(mm0, mm7);
1896 
1897 // tmp0 = tmp10 + tmp13;
1898 // tmp3 = tmp10 - tmp13;
1899  paddw_r2r(mm2, mm0); // [0,tmp0],[1,tmp0],[2,tmp0],[3,tmp0]
1900  psubw_r2r(mm2, mm7); // [0,tmp3],[1,tmp3],[2,tmp3],[3,tmp3]
1901 
1902 // tmp12 = MULTIPLY(tmp14, FIX_1_414213562) - tmp13;
1903  psubw_r2r(mm2, mm6); // wsptr[0,tmp12],[1,tmp12],[2,tmp12],[3,tmp12]
1904 // tmp1 = tmp11 + tmp12;
1905 // tmp2 = tmp11 - tmp12;
1906  movq_r2r(mm1, mm5);
1907 
1908  //OK
1909 
1910  /* Odd part */
1911 
1912 // z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
1913 // z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
1914 // z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
1915 // z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
1916  movq_m2r(*(wsptr), mm3); // wsptr[0,0],[0,1],[0,2],[0,3]
1917  paddw_r2r(mm6, mm1); // [0,tmp1],[1,tmp1],[2,tmp1],[3,tmp1]
1918 
1919  movq_m2r(*(wsptr+1), mm4); // wsptr[0,4],[0,5],[0,6],[0,7]
1920  psubw_r2r(mm6, mm5); // [0,tmp2],[1,tmp2],[2,tmp2],[3,tmp2]
1921 
1922  movq_r2r(mm3, mm6);
1923  punpckldq_r2r(mm4, mm3); // wsptr[0,0],[0,1],[0,4],[0,5]
1924 
1925  punpckhdq_r2r(mm6, mm4); // wsptr[0,6],[0,7],[0,2],[0,3]
1926  movq_r2r(mm3, mm2);
1927 
1928 //Save tmp0 and tmp1 in wsptr
1929  movq_r2m(mm0, *(wsptr)); // save tmp0
1930  paddw_r2r(mm4, mm2); // wsptr[xxx],[0,z11],[xxx],[0,z13]
1931 
1932 
1933 //Continue with z10 --- z13
1934  movq_m2r(*(wsptr+2), mm6); // wsptr[1,0],[1,1],[1,2],[1,3]
1935  psubw_r2r(mm4, mm3); // wsptr[xxx],[0,z12],[xxx],[0,z10]
1936 
1937  movq_m2r(*(wsptr+3), mm0); // wsptr[1,4],[1,5],[1,6],[1,7]
1938  movq_r2r(mm6, mm4);
1939 
1940  movq_r2m(mm1, *(wsptr+1)); // save tmp1
1941  punpckldq_r2r(mm0, mm6); // wsptr[1,0],[1,1],[1,4],[1,5]
1942 
1943  punpckhdq_r2r(mm4, mm0); // wsptr[1,6],[1,7],[1,2],[1,3]
1944  movq_r2r(mm6, mm1);
1945 
1946 //Save tmp2 and tmp3 in wsptr
1947  paddw_r2r(mm0, mm6); // wsptr[xxx],[1,z11],[xxx],[1,z13]
1948  movq_r2r(mm2, mm4);
1949 
1950 //Continue with z10 --- z13
1951  movq_r2m(mm5, *(wsptr+2)); // save tmp2
1952  punpcklwd_r2r(mm6, mm2); // wsptr[xxx],[xxx],[0,z11],[1,z11]
1953 
1954  psubw_r2r(mm0, mm1); // wsptr[xxx],[1,z12],[xxx],[1,z10]
1955  punpckhwd_r2r(mm6, mm4); // wsptr[xxx],[xxx],[0,z13],[1,z13]
1956 
1957  movq_r2r(mm3, mm0);
1958  punpcklwd_r2r(mm1, mm3); // wsptr[xxx],[xxx],[0,z12],[1,z12]
1959 
1960  movq_r2m(mm7, *(wsptr+3)); // save tmp3
1961  punpckhwd_r2r(mm1, mm0); // wsptr[xxx],[xxx],[0,z10],[1,z10]
1962 
1963  movq_m2r(*(wsptr+4), mm6); // wsptr[2,0],[2,1],[2,2],[2,3]
1964  punpckhdq_r2r(mm2, mm0); // wsptr[0,z10],[1,z10],[0,z11],[1,z11]
1965 
1966  movq_m2r(*(wsptr+5), mm7); // wsptr[2,4],[2,5],[2,6],[2,7]
1967  punpckhdq_r2r(mm4, mm3); // wsptr[0,z12],[1,z12],[0,z13],[1,z13]
1968 
1969  movq_m2r(*(wsptr+6), mm1); // wsptr[3,0],[3,1],[3,2],[3,3]
1970  movq_r2r(mm6, mm4);
1971 
1972  punpckldq_r2r(mm7, mm6); // wsptr[2,0],[2,1],[2,4],[2,5]
1973  movq_r2r(mm1, mm5);
1974 
1975  punpckhdq_r2r(mm4, mm7); // wsptr[2,6],[2,7],[2,2],[2,3]
1976  movq_r2r(mm6, mm2);
1977 
1978  movq_m2r(*(wsptr+7), mm4); // wsptr[3,4],[3,5],[3,6],[3,7]
1979  paddw_r2r(mm7, mm6); // wsptr[xxx],[2,z11],[xxx],[2,z13]
1980 
1981  psubw_r2r(mm7, mm2); // wsptr[xxx],[2,z12],[xxx],[2,z10]
1982  punpckldq_r2r(mm4, mm1); // wsptr[3,0],[3,1],[3,4],[3,5]
1983 
1984  punpckhdq_r2r(mm5, mm4); // wsptr[3,6],[3,7],[3,2],[3,3]
1985  movq_r2r(mm1, mm7);
1986 
1987  paddw_r2r(mm4, mm1); // wsptr[xxx],[3,z11],[xxx],[3,z13]
1988  psubw_r2r(mm4, mm7); // wsptr[xxx],[3,z12],[xxx],[3,z10]
1989 
1990  movq_r2r(mm6, mm5);
1991  punpcklwd_r2r(mm1, mm6); // wsptr[xxx],[xxx],[2,z11],[3,z11]
1992 
1993  punpckhwd_r2r(mm1, mm5); // wsptr[xxx],[xxx],[2,z13],[3,z13]
1994  movq_r2r(mm2, mm4);
1995 
1996  punpcklwd_r2r(mm7, mm2); // wsptr[xxx],[xxx],[2,z12],[3,z12]
1997 
1998  punpckhwd_r2r(mm7, mm4); // wsptr[xxx],[xxx],[2,z10],[3,z10]
1999 
2000  punpckhdq_r2r(mm6, mm4);
2001 
2002  punpckhdq_r2r(mm5, mm2); // wsptr[2,z12],[3,z12],[2,z13],[3,z13]
2003  movq_r2r(mm0, mm5);
2004 
2005  punpckldq_r2r(mm4, mm0); // wsptr[0,z10],[1,z10],[2,z10],[3,z10]
2006 
2007  punpckhdq_r2r(mm4, mm5); // wsptr[0,z11],[1,z11],[2,z11],[3,z11]
2008  movq_r2r(mm3, mm4);
2009 
2010  punpckhdq_r2r(mm2, mm4); // wsptr[0,z13],[1,z13],[2,z13],[3,z13]
2011  movq_r2r(mm5, mm1);
2012 
2013  punpckldq_r2r(mm2, mm3); // wsptr[0,z12],[1,z12],[2,z12],[3,z12]
2014 // tmp7 = z11 + z13; /* phase 5 */
2015 // tmp8 = z11 - z13; /* phase 5 */
2016  psubw_r2r(mm4, mm1); // tmp8
2017 
2018  paddw_r2r(mm4, mm5); // tmp7
2019 // tmp21 = MULTIPLY(tmp8, FIX_1_414213562); /* 2*c4 */
2020  psllw_i2r(2, mm1);
2021 
2022  psllw_i2r(2, mm0);
2023 
2024  pmulhw_m2r(fix_141, mm1); // tmp21
2025 // tmp20 = MULTIPLY(z12, (FIX_1_082392200- FIX_1_847759065)) /* 2*(c2-c6) */
2026 // + MULTIPLY(z10, - FIX_1_847759065); /* 2*c2 */
2027  psllw_i2r(2, mm3);
2028  movq_r2r(mm0, mm7);
2029 
2030  pmulhw_m2r(fix_n184, mm7);
2031  movq_r2r(mm3, mm6);
2032 
2033  movq_m2r(*(wsptr), mm2); // tmp0,final1
2034 
2035  pmulhw_m2r(fix_108n184, mm6);
2036 // tmp22 = MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) /* -2*(c2+c6) */
2037 // + MULTIPLY(z12, FIX_1_847759065); /* 2*c2 */
2038  movq_r2r(mm2, mm4); // final1
2039 
2040  pmulhw_m2r(fix_184n261, mm0);
2041  paddw_r2r(mm5, mm2); // tmp0+tmp7,final1
2042 
2043  pmulhw_m2r(fix_184, mm3);
2044  psubw_r2r(mm5, mm4); // tmp0-tmp7,final1
2045 
2046 // tmp6 = tmp22 - tmp7; /* phase 2 */
2047  psraw_i2r(3, mm2); // outptr[0,0],[1,0],[2,0],[3,0],final1
2048 
2049  paddw_r2r(mm6, mm7); // tmp20
2050  psraw_i2r(3, mm4); // outptr[0,7],[1,7],[2,7],[3,7],final1
2051 
2052  paddw_r2r(mm0, mm3); // tmp22
2053 
2054 // tmp5 = tmp21 - tmp6;
2055  psubw_r2r(mm5, mm3); // tmp6
2056 
2057 // tmp4 = tmp20 + tmp5;
2058  movq_m2r(*(wsptr+1), mm0); // tmp1,final2
2059  psubw_r2r(mm3, mm1); // tmp5
2060 
2061  movq_r2r(mm0, mm6); // final2
2062  paddw_r2r(mm3, mm0); // tmp1+tmp6,final2
2063 
2064  /* Final output stage: scale down by a factor of 8 and range-limit */
2065 
2066 
2067 // outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
2068 // & RANGE_MASK];
2069 // outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
2070 // & RANGE_MASK]; final1
2071 
2072 
2073 // outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
2074 // & RANGE_MASK];
2075 // outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
2076 // & RANGE_MASK]; final2
2077  psubw_r2r(mm3, mm6); // tmp1-tmp6,final2
2078  psraw_i2r(3, mm0); // outptr[0,1],[1,1],[2,1],[3,1]
2079 
2080  psraw_i2r(3, mm6); // outptr[0,6],[1,6],[2,6],[3,6]
2081 
2082  packuswb_r2r(mm4, mm0); // out[0,1],[1,1],[2,1],[3,1],[0,7],[1,7],[2,7],[3,7]
2083 
2084  movq_m2r(*(wsptr+2), mm5); // tmp2,final3
2085  packuswb_r2r(mm6, mm2); // out[0,0],[1,0],[2,0],[3,0],[0,6],[1,6],[2,6],[3,6]
2086 
2087 // outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
2088 // & RANGE_MASK];
2089 // outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
2090 // & RANGE_MASK]; final3
2091  paddw_r2r(mm1, mm7); // tmp4
2092  movq_r2r(mm5, mm3);
2093 
2094  paddw_r2r(mm1, mm5); // tmp2+tmp5
2095  psubw_r2r(mm1, mm3); // tmp2-tmp5
2096 
2097  psraw_i2r(3, mm5); // outptr[0,2],[1,2],[2,2],[3,2]
2098 
2099  movq_m2r(*(wsptr+3), mm4); // tmp3,final4
2100  psraw_i2r(3, mm3); // outptr[0,5],[1,5],[2,5],[3,5]
2101 
2102 
2103 
2104 // outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
2105 // & RANGE_MASK];
2106 // outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
2107 // & RANGE_MASK]; final4
2108  movq_r2r(mm4, mm6);
2109  paddw_r2r(mm7, mm4); // tmp3+tmp4
2110 
2111  psubw_r2r(mm7, mm6); // tmp3-tmp4
2112  psraw_i2r(3, mm4); // outptr[0,4],[1,4],[2,4],[3,4]
2113 
2114  // mov ecx, [dataptr]
2115 
2116  psraw_i2r(3, mm6); // outptr[0,3],[1,3],[2,3],[3,3]
2117 
2118  packuswb_r2r(mm4, mm5); // out[0,2],[1,2],[2,2],[3,2],[0,4],[1,4],[2,4],[3,4]
2119 
2120  packuswb_r2r(mm3, mm6); // out[0,3],[1,3],[2,3],[3,3],[0,5],[1,5],[2,5],[3,5]
2121  movq_r2r(mm2, mm4);
2122 
2123  movq_r2r(mm5, mm7);
2124  punpcklbw_r2r(mm0, mm2); // out[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1]
2125 
2126  punpckhbw_r2r(mm0, mm4); // out[0,6],[0,7],[1,6],[1,7],[2,6],[2,7],[3,6],[3,7]
2127  movq_r2r(mm2, mm1);
2128 
2129  punpcklbw_r2r(mm6, mm5); // out[0,2],[0,3],[1,2],[1,3],[2,2],[2,3],[3,2],[3,3]
2130 
2131  // add dataptr, 4
2132 
2133  punpckhbw_r2r(mm6, mm7); // out[0,4],[0,5],[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]
2134 
2135  punpcklwd_r2r(mm5, mm2); // out[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3]
2136 
2137  // add ecx, output_col
2138 
2139  movq_r2r(mm7, mm6);
2140  punpckhwd_r2r(mm5, mm1); // out[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]
2141 
2142  movq_r2r(mm2, mm0);
2143  punpcklwd_r2r(mm4, mm6); // out[0,4],[0,5],[0,6],[0,7],[1,4],[1,5],[1,6],[1,7]
2144 
2145  // mov idata, [dataptr]
2146 
2147  punpckldq_r2r(mm6, mm2); // out[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7]
2148 
2149  // add dataptr, 4
2150 
2151  movq_r2r(mm1, mm3);
2152 
2153  // add idata, output_col
2154 
2155  punpckhwd_r2r(mm4, mm7); // out[2,4],[2,5],[2,6],[2,7],[3,4],[3,5],[3,6],[3,7]
2156 
2157  movq_r2m(mm2, *(dataptr));
2158 
2159  punpckhdq_r2r(mm6, mm0); // out[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7]
2160 
2161  dataptr += rskip;
2162  movq_r2m(mm0, *(dataptr));
2163 
2164  punpckldq_r2r(mm7, mm1); // out[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7]
2165  punpckhdq_r2r(mm7, mm3); // out[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7]
2166 
2167  dataptr += rskip;
2168  movq_r2m(mm1, *(dataptr));
2169 
2170  dataptr += rskip;
2171  movq_r2m(mm3, *(dataptr));
2172 
2173 /*******************************************************************/
2174 
2175  wsptr += 8;
2176 
2177 /*******************************************************************/
2178 
2179 // tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
2180 // tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
2181 // tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
2182 // tmp14 = ((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6]);
2183  movq_m2r(*(wsptr), mm0); // wsptr[0,0],[0,1],[0,2],[0,3]
2184 
2185  movq_m2r(*(wsptr+1), mm1); // wsptr[0,4],[0,5],[0,6],[0,7]
2186  movq_r2r(mm0, mm2);
2187 
2188  movq_m2r(*(wsptr+2), mm3); // wsptr[1,0],[1,1],[1,2],[1,3]
2189  paddw_r2r(mm1, mm0); // wsptr[0,tmp10],[xxx],[0,tmp13],[xxx]
2190 
2191  movq_m2r(*(wsptr+3), mm4); // wsptr[1,4],[1,5],[1,6],[1,7]
2192  psubw_r2r(mm1, mm2); // wsptr[0,tmp11],[xxx],[0,tmp14],[xxx]
2193 
2194  movq_r2r(mm0, mm6);
2195  movq_r2r(mm3, mm5);
2196 
2197  paddw_r2r(mm4, mm3); // wsptr[1,tmp10],[xxx],[1,tmp13],[xxx]
2198  movq_r2r(mm2, mm1);
2199 
2200  psubw_r2r(mm4, mm5); // wsptr[1,tmp11],[xxx],[1,tmp14],[xxx]
2201  punpcklwd_r2r(mm3, mm0); // wsptr[0,tmp10],[1,tmp10],[xxx],[xxx]
2202 
2203  movq_m2r(*(wsptr+7), mm7); // wsptr[3,4],[3,5],[3,6],[3,7]
2204  punpckhwd_r2r(mm3, mm6); // wsptr[0,tmp13],[1,tmp13],[xxx],[xxx]
2205 
2206  movq_m2r(*(wsptr+4), mm3); // wsptr[2,0],[2,1],[2,2],[2,3]
2207  punpckldq_r2r(mm6, mm0); // wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
2208 
2209  punpcklwd_r2r(mm5, mm1); // wsptr[0,tmp11],[1,tmp11],[xxx],[xxx]
2210  movq_r2r(mm3, mm4);
2211 
2212  movq_m2r(*(wsptr+6), mm6); // wsptr[3,0],[3,1],[3,2],[3,3]
2213  punpckhwd_r2r(mm5, mm2); // wsptr[0,tmp14],[1,tmp14],[xxx],[xxx]
2214 
2215  movq_m2r(*(wsptr+5), mm5); // wsptr[2,4],[2,5],[2,6],[2,7]
2216  punpckldq_r2r(mm2, mm1); // wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
2217 
2218  paddw_r2r(mm5, mm3); // wsptr[2,tmp10],[xxx],[2,tmp13],[xxx]
2219  movq_r2r(mm6, mm2);
2220 
2221  psubw_r2r(mm5, mm4); // wsptr[2,tmp11],[xxx],[2,tmp14],[xxx]
2222  paddw_r2r(mm7, mm6); // wsptr[3,tmp10],[xxx],[3,tmp13],[xxx]
2223 
2224  movq_r2r(mm3, mm5);
2225  punpcklwd_r2r(mm6, mm3); // wsptr[2,tmp10],[3,tmp10],[xxx],[xxx]
2226 
2227  psubw_r2r(mm7, mm2); // wsptr[3,tmp11],[xxx],[3,tmp14],[xxx]
2228  punpckhwd_r2r(mm6, mm5); // wsptr[2,tmp13],[3,tmp13],[xxx],[xxx]
2229 
2230  movq_r2r(mm4, mm7);
2231  punpckldq_r2r(mm5, mm3); // wsptr[2,tmp10],[3,tmp10],[2,tmp13],[3,tmp13]
2232 
2233  punpcklwd_r2r(mm2, mm4); // wsptr[2,tmp11],[3,tmp11],[xxx],[xxx]
2234 
2235  punpckhwd_r2r(mm2, mm7); // wsptr[2,tmp14],[3,tmp14],[xxx],[xxx]
2236 
2237  punpckldq_r2r(mm7, mm4); // wsptr[2,tmp11],[3,tmp11],[2,tmp14],[3,tmp14]
2238  movq_r2r(mm1, mm6);
2239 
2240  //OK
2241 
2242 // mm0 = ;wsptr[0,tmp10],[1,tmp10],[0,tmp13],[1,tmp13]
2243 // mm1 = ;wsptr[0,tmp11],[1,tmp11],[0,tmp14],[1,tmp14]
2244 
2245  movq_r2r(mm0, mm2);
2246  punpckhdq_r2r(mm4, mm6); // wsptr[0,tmp14],[1,tmp14],[2,tmp14],[3,tmp14]
2247 
2248  punpckldq_r2r(mm4, mm1); // wsptr[0,tmp11],[1,tmp11],[2,tmp11],[3,tmp11]
2249  psllw_i2r(2, mm6);
2250 
2251  pmulhw_m2r(fix_141, mm6);
2252  punpckldq_r2r(mm3, mm0); // wsptr[0,tmp10],[1,tmp10],[2,tmp10],[3,tmp10]
2253 
2254  punpckhdq_r2r(mm3, mm2); // wsptr[0,tmp13],[1,tmp13],[2,tmp13],[3,tmp13]
2255  movq_r2r(mm0, mm7);
2256 
2257 // tmp0 = tmp10 + tmp13;
2258 // tmp3 = tmp10 - tmp13;
2259  paddw_r2r(mm2, mm0); // [0,tmp0],[1,tmp0],[2,tmp0],[3,tmp0]
2260  psubw_r2r(mm2, mm7); // [0,tmp3],[1,tmp3],[2,tmp3],[3,tmp3]
2261 
2262 // tmp12 = MULTIPLY(tmp14, FIX_1_414213562) - tmp13;
2263  psubw_r2r(mm2, mm6); // wsptr[0,tmp12],[1,tmp12],[2,tmp12],[3,tmp12]
2264 // tmp1 = tmp11 + tmp12;
2265 // tmp2 = tmp11 - tmp12;
2266  movq_r2r(mm1, mm5);
2267 
2268  //OK
2269 
2270 
2271  /* Odd part */
2272 
2273 // z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
2274 // z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
2275 // z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
2276 // z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
2277  movq_m2r(*(wsptr), mm3); // wsptr[0,0],[0,1],[0,2],[0,3]
2278  paddw_r2r(mm6, mm1); // [0,tmp1],[1,tmp1],[2,tmp1],[3,tmp1]
2279 
2280  movq_m2r(*(wsptr+1), mm4); // wsptr[0,4],[0,5],[0,6],[0,7]
2281  psubw_r2r(mm6, mm5); // [0,tmp2],[1,tmp2],[2,tmp2],[3,tmp2]
2282 
2283  movq_r2r(mm3, mm6);
2284  punpckldq_r2r(mm4, mm3); // wsptr[0,0],[0,1],[0,4],[0,5]
2285 
2286  punpckhdq_r2r(mm6, mm4); // wsptr[0,6],[0,7],[0,2],[0,3]
2287  movq_r2r(mm3, mm2);
2288 
2289 //Save tmp0 and tmp1 in wsptr
2290  movq_r2m(mm0, *(wsptr)); // save tmp0
2291  paddw_r2r(mm4, mm2); // wsptr[xxx],[0,z11],[xxx],[0,z13]
2292 
2293 
2294 //Continue with z10 --- z13
2295  movq_m2r(*(wsptr+2), mm6); // wsptr[1,0],[1,1],[1,2],[1,3]
2296  psubw_r2r(mm4, mm3); // wsptr[xxx],[0,z12],[xxx],[0,z10]
2297 
2298  movq_m2r(*(wsptr+3), mm0); // wsptr[1,4],[1,5],[1,6],[1,7]
2299  movq_r2r(mm6, mm4);
2300 
2301  movq_r2m(mm1, *(wsptr+1)); // save tmp1
2302  punpckldq_r2r(mm0, mm6); // wsptr[1,0],[1,1],[1,4],[1,5]
2303 
2304  punpckhdq_r2r(mm4, mm0); // wsptr[1,6],[1,7],[1,2],[1,3]
2305  movq_r2r(mm6, mm1);
2306 
2307 //Save tmp2 and tmp3 in wsptr
2308  paddw_r2r(mm0, mm6); // wsptr[xxx],[1,z11],[xxx],[1,z13]
2309  movq_r2r(mm2, mm4);
2310 
2311 //Continue with z10 --- z13
2312  movq_r2m(mm5, *(wsptr+2)); // save tmp2
2313  punpcklwd_r2r(mm6, mm2); // wsptr[xxx],[xxx],[0,z11],[1,z11]
2314 
2315  psubw_r2r(mm0, mm1); // wsptr[xxx],[1,z12],[xxx],[1,z10]
2316  punpckhwd_r2r(mm6, mm4); // wsptr[xxx],[xxx],[0,z13],[1,z13]
2317 
2318  movq_r2r(mm3, mm0);
2319  punpcklwd_r2r(mm1, mm3); // wsptr[xxx],[xxx],[0,z12],[1,z12]
2320 
2321  movq_r2m(mm7, *(wsptr+3)); // save tmp3
2322  punpckhwd_r2r(mm1, mm0); // wsptr[xxx],[xxx],[0,z10],[1,z10]
2323 
2324  movq_m2r(*(wsptr+4), mm6); // wsptr[2,0],[2,1],[2,2],[2,3]
2325  punpckhdq_r2r(mm2, mm0); // wsptr[0,z10],[1,z10],[0,z11],[1,z11]
2326 
2327  movq_m2r(*(wsptr+5), mm7); // wsptr[2,4],[2,5],[2,6],[2,7]
2328  punpckhdq_r2r(mm4, mm3); // wsptr[0,z12],[1,z12],[0,z13],[1,z13]
2329 
2330  movq_m2r(*(wsptr+6), mm1); // wsptr[3,0],[3,1],[3,2],[3,3]
2331  movq_r2r(mm6, mm4);
2332 
2333  punpckldq_r2r(mm7, mm6); // wsptr[2,0],[2,1],[2,4],[2,5]
2334  movq_r2r(mm1, mm5);
2335 
2336  punpckhdq_r2r(mm4, mm7); // wsptr[2,6],[2,7],[2,2],[2,3]
2337  movq_r2r(mm6, mm2);
2338 
2339  movq_m2r(*(wsptr+7), mm4); // wsptr[3,4],[3,5],[3,6],[3,7]
2340  paddw_r2r(mm7, mm6); // wsptr[xxx],[2,z11],[xxx],[2,z13]
2341 
2342  psubw_r2r(mm7, mm2); // wsptr[xxx],[2,z12],[xxx],[2,z10]
2343  punpckldq_r2r(mm4, mm1); // wsptr[3,0],[3,1],[3,4],[3,5]
2344 
2345  punpckhdq_r2r(mm5, mm4); // wsptr[3,6],[3,7],[3,2],[3,3]
2346  movq_r2r(mm1, mm7);
2347 
2348  paddw_r2r(mm4, mm1); // wsptr[xxx],[3,z11],[xxx],[3,z13]
2349  psubw_r2r(mm4, mm7); // wsptr[xxx],[3,z12],[xxx],[3,z10]
2350 
2351  movq_r2r(mm6, mm5);
2352  punpcklwd_r2r(mm1, mm6); // wsptr[xxx],[xxx],[2,z11],[3,z11]
2353 
2354  punpckhwd_r2r(mm1, mm5); // wsptr[xxx],[xxx],[2,z13],[3,z13]
2355  movq_r2r(mm2, mm4);
2356 
2357  punpcklwd_r2r(mm7, mm2); // wsptr[xxx],[xxx],[2,z12],[3,z12]
2358 
2359  punpckhwd_r2r(mm7, mm4); // wsptr[xxx],[xxx],[2,z10],[3,z10]
2360 
2361  punpckhdq_r2r(mm6, mm4); // wsptr[2,z10],[3,z10],[2,z11],[3,z11]
2362 
2363  punpckhdq_r2r(mm5, mm2); // wsptr[2,z12],[3,z12],[2,z13],[3,z13]
2364  movq_r2r(mm0, mm5);
2365 
2366  punpckldq_r2r(mm4, mm0); // wsptr[0,z10],[1,z10],[2,z10],[3,z10]
2367 
2368  punpckhdq_r2r(mm4, mm5); // wsptr[0,z11],[1,z11],[2,z11],[3,z11]
2369  movq_r2r(mm3, mm4);
2370 
2371  punpckhdq_r2r(mm2, mm4); // wsptr[0,z13],[1,z13],[2,z13],[3,z13]
2372  movq_r2r(mm5, mm1);
2373 
2374  punpckldq_r2r(mm2, mm3); // wsptr[0,z12],[1,z12],[2,z12],[3,z12]
2375 // tmp7 = z11 + z13; /* phase 5 */
2376 // tmp8 = z11 - z13; /* phase 5 */
2377  psubw_r2r(mm4, mm1); // tmp8
2378 
2379  paddw_r2r(mm4, mm5); // tmp7
2380 // tmp21 = MULTIPLY(tmp8, FIX_1_414213562); /* 2*c4 */
2381  psllw_i2r(2, mm1);
2382 
2383  psllw_i2r(2, mm0);
2384 
2385  pmulhw_m2r(fix_141, mm1); // tmp21
2386 // tmp20 = MULTIPLY(z12, (FIX_1_082392200- FIX_1_847759065)) /* 2*(c2-c6) */
2387 // + MULTIPLY(z10, - FIX_1_847759065); /* 2*c2 */
2388  psllw_i2r(2, mm3);
2389  movq_r2r(mm0, mm7);
2390 
2391  pmulhw_m2r(fix_n184, mm7);
2392  movq_r2r(mm3, mm6);
2393 
2394  movq_m2r(*(wsptr), mm2); // tmp0,final1
2395 
2396  pmulhw_m2r(fix_108n184, mm6);
2397 // tmp22 = MULTIPLY(z10,(FIX_1_847759065 - FIX_2_613125930)) /* -2*(c2+c6) */
2398 // + MULTIPLY(z12, FIX_1_847759065); /* 2*c2 */
2399  movq_r2r(mm2, mm4); // final1
2400 
2401  pmulhw_m2r(fix_184n261, mm0);
2402  paddw_r2r(mm5, mm2); // tmp0+tmp7,final1
2403 
2404  pmulhw_m2r(fix_184, mm3);
2405  psubw_r2r(mm5, mm4); // tmp0-tmp7,final1
2406 
2407 // tmp6 = tmp22 - tmp7; /* phase 2 */
2408  psraw_i2r(3, mm2); // outptr[0,0],[1,0],[2,0],[3,0],final1
2409 
2410  paddw_r2r(mm6, mm7); // tmp20
2411  psraw_i2r(3, mm4); // outptr[0,7],[1,7],[2,7],[3,7],final1
2412 
2413  paddw_r2r(mm0, mm3); // tmp22
2414 
2415 // tmp5 = tmp21 - tmp6;
2416  psubw_r2r(mm5, mm3); // tmp6
2417 
2418 // tmp4 = tmp20 + tmp5;
2419  movq_m2r(*(wsptr+1), mm0); // tmp1,final2
2420  psubw_r2r(mm3, mm1); // tmp5
2421 
2422  movq_r2r(mm0, mm6); // final2
2423  paddw_r2r(mm3, mm0); // tmp1+tmp6,final2
2424 
2425  /* Final output stage: scale down by a factor of 8 and range-limit */
2426 
2427 // outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
2428 // & RANGE_MASK];
2429 // outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
2430 // & RANGE_MASK]; final1
2431 
2432 
2433 // outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
2434 // & RANGE_MASK];
2435 // outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
2436 // & RANGE_MASK]; final2
2437  psubw_r2r(mm3, mm6); // tmp1-tmp6,final2
2438  psraw_i2r(3, mm0); // outptr[0,1],[1,1],[2,1],[3,1]
2439 
2440  psraw_i2r(3, mm6); // outptr[0,6],[1,6],[2,6],[3,6]
2441 
2442  packuswb_r2r(mm4, mm0); // out[0,1],[1,1],[2,1],[3,1],[0,7],[1,7],[2,7],[3,7]
2443 
2444  movq_m2r(*(wsptr+2), mm5); // tmp2,final3
2445  packuswb_r2r(mm6, mm2); // out[0,0],[1,0],[2,0],[3,0],[0,6],[1,6],[2,6],[3,6]
2446 
2447 // outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
2448 // & RANGE_MASK];
2449 // outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
2450 // & RANGE_MASK]; final3
2451  paddw_r2r(mm1, mm7); // tmp4
2452  movq_r2r(mm5, mm3);
2453 
2454  paddw_r2r(mm1, mm5); // tmp2+tmp5
2455  psubw_r2r(mm1, mm3); // tmp2-tmp5
2456 
2457  psraw_i2r(3, mm5); // outptr[0,2],[1,2],[2,2],[3,2]
2458 
2459  movq_m2r(*(wsptr+3), mm4); // tmp3,final4
2460  psraw_i2r(3, mm3); // outptr[0,5],[1,5],[2,5],[3,5]
2461 
2462 
2463 
2464 // outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
2465 // & RANGE_MASK];
2466 // outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
2467 // & RANGE_MASK]; final4
2468  movq_r2r(mm4, mm6);
2469  paddw_r2r(mm7, mm4); // tmp3+tmp4
2470 
2471  psubw_r2r(mm7, mm6); // tmp3-tmp4
2472  psraw_i2r(3, mm4); // outptr[0,4],[1,4],[2,4],[3,4]
2473 
2474  psraw_i2r(3, mm6); // outptr[0,3],[1,3],[2,3],[3,3]
2475 
2476  /*
2477  movq_r2m(mm4, *dummy);
2478  fprintf(stderr, "3-4 %016llx\n", dummy);
2479  movq_r2m(mm4, *dummy);
2480  fprintf(stderr, "3+4 %016llx\n", dummy);
2481  */
2482 
2483 
2484  packuswb_r2r(mm4, mm5); // out[0,2],[1,2],[2,2],[3,2],[0,4],[1,4],[2,4],[3,4]
2485 
2486  packuswb_r2r(mm3, mm6); // out[0,3],[1,3],[2,3],[3,3],[0,5],[1,5],[2,5],[3,5]
2487  movq_r2r(mm2, mm4);
2488 
2489  movq_r2r(mm5, mm7);
2490  punpcklbw_r2r(mm0, mm2); // out[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1]
2491 
2492  punpckhbw_r2r(mm0, mm4); // out[0,6],[0,7],[1,6],[1,7],[2,6],[2,7],[3,6],[3,7]
2493  movq_r2r(mm2, mm1);
2494 
2495  punpcklbw_r2r(mm6, mm5); // out[0,2],[0,3],[1,2],[1,3],[2,2],[2,3],[3,2],[3,3]
2496 
2497  punpckhbw_r2r(mm6, mm7); // out[0,4],[0,5],[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]
2498 
2499  punpcklwd_r2r(mm5, mm2); // out[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3]
2500 
2501  movq_r2r(mm7, mm6);
2502  punpckhwd_r2r(mm5, mm1); // out[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]
2503 
2504  movq_r2r(mm2, mm0);
2505  punpcklwd_r2r(mm4, mm6); // out[0,4],[0,5],[0,6],[0,7],[1,4],[1,5],[1,6],[1,7]
2506 
2507  punpckldq_r2r(mm6, mm2); // out[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7]
2508 
2509  movq_r2r(mm1, mm3);
2510 
2511  punpckhwd_r2r(mm4, mm7); // out[2,4],[2,5],[2,6],[2,7],[3,4],[3,5],[3,6],[3,7]
2512 
2513  dataptr += rskip;
2514  movq_r2m(mm2, *(dataptr));
2515 
2516  punpckhdq_r2r(mm6, mm0); // out[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7]
2517 
2518  dataptr += rskip;
2519  movq_r2m(mm0, *(dataptr));
2520 
2521  punpckldq_r2r(mm7, mm1); // out[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7]
2522 
2523  punpckhdq_r2r(mm7, mm3); // out[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7]
2524 
2525  dataptr += rskip;
2526  movq_r2m(mm1, *(dataptr));
2527 
2528  dataptr += rskip;
2529  movq_r2m(mm3, *(dataptr));
2530 
2531 #else
2532  int32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
2533  int32_t tmp10, tmp11, tmp12, tmp13;
2534  int32_t z5, z10, z11, z12, z13;
2535  int16_t *inptr;
2536  int32_t *wsptr;
2537  uint8_t *outptr;
2538  int ctr;
2539  int32_t dcval;
2540 
2541  inptr = data;
2542  wsptr = ws;
2543  for (ctr = 8; ctr > 0; ctr--) {
2544 
2545  if ((inptr[8] | inptr[16] | inptr[24] |
2546  inptr[32] | inptr[40] | inptr[48] | inptr[56]) == 0) {
2547  dcval = inptr[0];
2548  wsptr[0] = dcval;
2549  wsptr[8] = dcval;
2550  wsptr[16] = dcval;
2551  wsptr[24] = dcval;
2552  wsptr[32] = dcval;
2553  wsptr[40] = dcval;
2554  wsptr[48] = dcval;
2555  wsptr[56] = dcval;
2556 
2557  inptr++;
2558  wsptr++;
2559  continue;
2560  }
2561 
2562  tmp0 = inptr[0];
2563  tmp1 = inptr[16];
2564  tmp2 = inptr[32];
2565  tmp3 = inptr[48];
2566 
2567  tmp10 = tmp0 + tmp2;
2568  tmp11 = tmp0 - tmp2;
2569 
2570  tmp13 = tmp1 + tmp3;
2571  tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13;
2572 
2573  tmp0 = tmp10 + tmp13;
2574  tmp3 = tmp10 - tmp13;
2575  tmp1 = tmp11 + tmp12;
2576  tmp2 = tmp11 - tmp12;
2577 
2578  tmp4 = inptr[8];
2579  tmp5 = inptr[24];
2580  tmp6 = inptr[40];
2581  tmp7 = inptr[56];
2582 
2583  z13 = tmp6 + tmp5;
2584  z10 = tmp6 - tmp5;
2585  z11 = tmp4 + tmp7;
2586  z12 = tmp4 - tmp7;
2587 
2588  tmp7 = z11 + z13;
2589  tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
2590 
2591  z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
2592  tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
2593  tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
2594 
2595  tmp6 = tmp12 - tmp7;
2596  tmp5 = tmp11 - tmp6;
2597  tmp4 = tmp10 + tmp5;
2598 
2599  wsptr[0] = (int32_t) (tmp0 + tmp7);
2600  wsptr[56] = (int32_t) (tmp0 - tmp7);
2601  wsptr[8] = (int32_t) (tmp1 + tmp6);
2602  wsptr[48] = (int32_t) (tmp1 - tmp6);
2603  wsptr[16] = (int32_t) (tmp2 + tmp5);
2604  wsptr[40] = (int32_t) (tmp2 - tmp5);
2605  wsptr[32] = (int32_t) (tmp3 + tmp4);
2606  wsptr[24] = (int32_t) (tmp3 - tmp4);
2607 
2608  inptr++;
2609  wsptr++;
2610  }
2611 
2612  wsptr = ws;
2613  for (ctr = 0; ctr < 8; ctr++) {
2614  outptr = &(odata[ctr*rskip]);
2615 
2616  tmp10 = wsptr[0] + wsptr[4];
2617  tmp11 = wsptr[0] - wsptr[4];
2618 
2619  tmp13 = wsptr[2] + wsptr[6];
2620  tmp12 = MULTIPLY(wsptr[2] - wsptr[6], FIX_1_414213562) - tmp13;
2621 
2622  tmp0 = tmp10 + tmp13;
2623  tmp3 = tmp10 - tmp13;
2624  tmp1 = tmp11 + tmp12;
2625  tmp2 = tmp11 - tmp12;
2626 
2627  z13 = wsptr[5] + wsptr[3];
2628  z10 = wsptr[5] - wsptr[3];
2629  z11 = wsptr[1] + wsptr[7];
2630  z12 = wsptr[1] - wsptr[7];
2631 
2632  tmp7 = z11 + z13;
2633  tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
2634 
2635  z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
2636  tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
2637  tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
2638 
2639  tmp6 = tmp12 - tmp7;
2640  tmp5 = tmp11 - tmp6;
2641  tmp4 = tmp10 + tmp5;
2642 
2643  outptr[0] = RL(DESCALE(tmp0 + tmp7));
2644  outptr[7] = RL(DESCALE(tmp0 - tmp7));
2645  outptr[1] = RL(DESCALE(tmp1 + tmp6));
2646  outptr[6] = RL(DESCALE(tmp1 - tmp6));
2647  outptr[2] = RL(DESCALE(tmp2 + tmp5));
2648  outptr[5] = RL(DESCALE(tmp2 - tmp5));
2649  outptr[4] = RL(DESCALE(tmp3 + tmp4));
2650  outptr[3] = RL(DESCALE(tmp3 - tmp4));
2651 
2652  wsptr += 8;
2653  }
2654 #endif
2655 }
2656 
2657 inline void RTjpeg::CalcTbls(void)
2658 {
2659  int i;
2660  uint64_t qual;
2661 
2662  qual = (uint64_t)Q << (32 - 7); /* 32 bit FP, 255=2, 0=0 */
2663 
2664  for(i = 0; i < 64; i++)
2665  {
2666  lqt[i] = (int32_t)((qual/((uint64_t)RTjpeg_lum_quant_tbl[i]<<16))>>3);
2667  if (lqt[i] == 0)
2668  lqt[i]=1;
2669 
2670  cqt[i] = (int32_t)((qual/((uint64_t)RTjpeg_chrom_quant_tbl[i]<<16))>>3);
2671  if (cqt[i] == 0)
2672  cqt[i]=1;
2673 
2674  liqt[i] = (1<<16) / (lqt[i]<<3);
2675  ciqt[i] = (1<<16) / (cqt[i]<<3);
2676  lqt[i] = ((1<<16) / liqt[i])>>3;
2677  cqt[i] = ((1<<16) / ciqt[i])>>3;
2678  }
2679 
2680  lb8 = 0;
2681  while (liqt[RTjpeg_ZZ[++lb8]] <= 8)
2682  ;
2683  lb8--;
2684  cb8 = 0;
2685 
2686  while (ciqt[RTjpeg_ZZ[++cb8]] <= 8)
2687  ;
2688  cb8--;
2689 }
2690 
2691 int RTjpeg::SetQuality(int *quality)
2692 {
2693  if (*quality < 1)
2694  *quality = 1;
2695  if (*quality > 255)
2696  *quality = 255;
2697 
2698  Q = *quality;
2699 
2700  CalcTbls();
2701  DctInit();
2702  IdctInit();
2703  QuantInit();
2704 
2705  return 0;
2706 }
2707 
2708 int RTjpeg::SetFormat(const int *fmt)
2709 {
2710  f = *fmt;
2711  return 0;
2712 }
2713 
2714 int RTjpeg::SetSize(const int *w, const int *h)
2715 {
2716  if ((*w < 0) || (*w > 65535))
2717  return -1;
2718  if ((*h < 0) || (*h > 65535))
2719  return -1;
2720 
2721  width = *w;
2722  height = *h;
2723  Ywidth = width>>3;
2724  Ysize = width * height;
2725  Cwidth = width>>4;
2726  Csize = (width>>1) * height;
2727 
2728  if (key_rate > 0)
2729  {
2730  unsigned long tmp;
2731  if (old)
2732  delete [] old_start;
2733  old_start = new int16_t[((4*width*height)+32)];
2734 
2735  tmp = (unsigned long)old_start;
2736  tmp += 32;
2737  tmp = tmp>>5;
2738 
2739  old = (int16_t *)(tmp<<5);
2740  if (!old)
2741  {
2742  fprintf(stderr, "RTjpeg: Could not allocate memory\n");
2743  return -1;
2744  }
2745  memset(old, 0, ((4*width*height)));
2746  }
2747  return 0;
2748 }
2749 
2750 int RTjpeg::SetIntra(int *key, int *lm, int *cm)
2751 {
2752  unsigned long tmp;
2753 
2754  if (*key < 0)
2755  *key = 0;
2756  if (*key > 255)
2757  *key = 255;
2758  key_rate = *key;
2759 
2760  if (*lm < 0)
2761  *lm = 0;
2762  if (*lm > 16)
2763  *lm = 16;
2764  if (*cm < 0)
2765  *cm = 0;
2766  if (*cm > 16)
2767  *cm = 16;
2768 
2769 #ifdef MMX
2770  lmask.uq = (((uint64_t)(*lm)<<48)|((uint64_t)(*lm)<<32)|((uint64_t)(*lm)<<16)|(uint64_t)(*lm));
2771  cmask.uq = (((uint64_t)(*cm)<<48)|((uint64_t)(*cm)<<32)|((uint64_t)(*cm)<<16)|(uint64_t)(*cm));
2772 #else
2773  lmask = *lm;
2774  cmask = *cm;
2775 #endif
2776 
2777  if (old)
2778  delete [] old_start;
2779  old_start = new int16_t[((4*width*height)+32)];
2780  tmp = (unsigned long)old_start;
2781  tmp += 32;
2782  tmp = tmp >> 5;
2783  old = (int16_t *)(tmp << 5);
2784  if (!old)
2785  {
2786  fprintf(stderr, "RTjpeg: Could not allocate memory\n");
2787  return -1;
2788  }
2789  memset(old, 0, ((4*width*height)));
2790 
2791  return 0;
2792 }
2793 
2795 {
2796  for (int i = 0; i < 64; i++)
2797  {
2798  block[i] = 0;
2799  lqt[i] = cqt[i] = liqt[i] = ciqt[i] = 0;
2800  for (int j = 0; j < 4; j++)
2801  ws[i*j] = 0;
2802  }
2803  lb8 = cb8 = Ywidth = Cwidth = Ysize = Csize = key_count = 0;
2804  width = height = Q = f = key_rate = 0;
2805 
2806  old = old_start = nullptr;
2807 
2808 #ifdef MMX
2809  lmask.q = cmask.q = 0;
2810  RTjpeg_ones.q = 0x0001000100010001LL;
2811  RTjpeg_half.q = 0x7fff7fff7fff7fffLL;
2812  RTjpeg_C4.q = 0x2D412D412D412D41LL;
2813  RTjpeg_C6.q = 0x187E187E187E187ELL;
2814  RTjpeg_C2mC6.q= 0x22A322A322A322A3LL;
2815  RTjpeg_C2pC6.q= 0x539F539F539F539FLL;
2816  RTjpeg_zero.q = 0x0000000000000000LL;
2817 #else
2818  lmask = cmask = 0;
2819 #endif
2820 }
2821 
2823 {
2824  delete [] old_start;
2825 }
2826 
2827 inline int RTjpeg::compressYUV420(int8_t *sp, uint8_t **planes)
2828 {
2829  int8_t * sb;
2830  uint8_t * bp = planes[0];
2831  uint8_t * bp1 = bp + (width<<3);
2832  uint8_t * bp2 = planes[1];
2833  uint8_t * bp3 = planes[2];
2834  int i, j, k;
2835 
2836 #ifdef MMX
2837  emms();
2838 #endif
2839  sb = sp;
2840 /* Y */
2841  for(i = height >> 1; i; i -= 8)
2842  {
2843  for(j = 0, k = 0; j < width; j += 16, k += 8)
2844  {
2845  DctY(bp+j, Ywidth);
2846  Quant(block, lqt);
2847  sp += b2s(block, sp, lb8);
2848 
2849  DctY(bp+j+8, Ywidth);
2850  Quant(block, lqt);
2851  sp += b2s(block, sp, lb8);
2852 
2853  DctY(bp1+j, Ywidth);
2854  Quant(block, lqt);
2855  sp += b2s(block, sp, lb8);
2856 
2857  DctY(bp1+j+8, Ywidth);
2858  Quant(block, lqt);
2859  sp += b2s(block, sp, lb8);
2860 
2861  DctY(bp2+k, Cwidth);
2862  Quant(block, cqt);
2863  sp += b2s(block, sp, cb8);
2864 
2865  DctY(bp3+k, Cwidth);
2866  Quant(block, cqt);
2867  sp += b2s(block, sp, cb8);
2868  }
2869  bp += width<<4;
2870  bp1 += width<<4;
2871  bp2 += width<<2;
2872  bp3 += width<<2;
2873  }
2874 #ifdef MMX
2875  emms();
2876 #endif
2877  return (sp - sb);
2878 }
2879 
2880 inline int RTjpeg::compressYUV422(int8_t *sp, uint8_t **planes)
2881 {
2882  int8_t * sb;
2883  uint8_t * bp = planes[0];
2884  uint8_t * bp2 = planes[1];
2885  uint8_t * bp3 = planes[2];
2886  int i, j, k;
2887 
2888 #ifdef MMX
2889  emms();
2890 #endif
2891  sb=sp;
2892 /* Y */
2893  for(i=height; i; i-=8)
2894  {
2895  for(j=0, k=0; j<width; j+=16, k+=8)
2896  {
2897  DctY(bp+j, Ywidth);
2898  Quant(block, lqt);
2899  sp += b2s(block, sp, lb8);
2900 
2901  DctY(bp+j+8, Ywidth);
2902  Quant(block, lqt);
2903  sp += b2s(block, sp, lb8);
2904 
2905  DctY(bp2+k, Cwidth);
2906  Quant(block, cqt);
2907  sp+=b2s(block, sp, cb8);
2908 
2909  DctY(bp3+k, Cwidth);
2910  Quant(block, cqt);
2911  sp+=b2s(block, sp, cb8);
2912 
2913  }
2914  bp += width << 3;
2915  bp2 += width << 2;
2916  bp3 += width << 2;
2917 
2918  }
2919 #ifdef MMX
2920  emms();
2921 #endif
2922  return (sp-sb);
2923 }
2924 
2925 inline int RTjpeg::compress8(int8_t *sp, uint8_t **planes)
2926 {
2927  int8_t * sb;
2928  uint8_t * bp = planes[0];
2929  int i, j;
2930 
2931 #ifdef MMX
2932  emms();
2933 #endif
2934 
2935  sb=sp;
2936 /* Y */
2937  for(i=0; i<height; i+=8)
2938  {
2939  for(j=0; j<width; j+=8)
2940  {
2941  DctY(bp+j, width);
2942  Quant(block, lqt);
2943  sp += b2s(block, sp, lb8);
2944  }
2945  bp += width;
2946  }
2947 
2948 #ifdef MMX
2949  emms();
2950 #endif
2951  return (sp-sb);
2952 }
2953 
2954 inline void RTjpeg::decompressYUV422(int8_t *sp, uint8_t **planes)
2955 {
2956  uint8_t * bp = planes[0];
2957  uint8_t * bp2 = planes[1];
2958  uint8_t * bp3 = planes[2];
2959  int i, j,k;
2960 
2961 #ifdef MMX
2962  emms();
2963 #endif
2964 
2965 /* Y */
2966  for(i=height; i; i-=8)
2967  {
2968  for(k=0, j=0; j<width; j+=16, k+=8) {
2969  if (*sp==-1)sp++;
2970  else
2971  {
2972  sp += s2b(block, sp, lb8, liqt);
2973  Idct(bp+j, block, width);
2974  }
2975  if (*sp==-1)sp++;
2976  else
2977  {
2978  sp += s2b(block, sp, lb8, liqt);
2979  Idct(bp+j+8, block, width);
2980  }
2981  if (*sp==-1)sp++;
2982  else
2983  {
2984  sp += s2b(block, sp, cb8, ciqt);
2985  Idct(bp2+k, block, width>>1);
2986  }
2987  if (*sp==-1)sp++;
2988  else
2989  {
2990  sp += s2b(block, sp, cb8, ciqt);
2991  Idct(bp3+k, block, width>>1);
2992  }
2993  }
2994  bp += width<<3;
2995  bp2 += width<<2;
2996  bp3 += width<<2;
2997  }
2998 #ifdef MMX
2999  emms();
3000 #endif
3001 }
3002 
3003 inline void RTjpeg::decompressYUV420(int8_t *sp, uint8_t **planes)
3004 {
3005  uint8_t * bp = planes[0];
3006  uint8_t * bp1 = bp + (width<<3);
3007  uint8_t * bp2 = planes[1];
3008  uint8_t * bp3 = planes[2];
3009  int i, j,k;
3010 
3011 #ifdef MMX
3012  emms();
3013 #endif
3014 
3015 /* Y */
3016  for(i=height>>1; i; i-=8)
3017  {
3018  for(k=0, j=0; j<width; j+=16, k+=8) {
3019  if (*sp==-1)sp++;
3020  else
3021  {
3022  sp += s2b(block, sp, lb8, liqt);
3023  Idct(bp+j, block, width);
3024  }
3025  if (*sp==-1)sp++;
3026  else
3027  {
3028  sp += s2b(block, sp, lb8, liqt);
3029  Idct(bp+j+8, block, width);
3030  }
3031  if (*sp==-1)sp++;
3032  else
3033  {
3034  sp += s2b(block, sp, lb8, liqt);
3035  Idct(bp1+j, block, width);
3036  }
3037  if (*sp==-1)sp++;
3038  else
3039  {
3040  sp += s2b(block, sp, lb8, liqt);
3041  Idct(bp1+j+8, block, width);
3042  }
3043  if (*sp==-1)sp++;
3044  else
3045  {
3046  sp += s2b(block, sp, cb8, ciqt);
3047  Idct(bp2+k, block, width>>1);
3048  }
3049  if (*sp==-1)sp++;
3050  else
3051  {
3052  sp += s2b(block, sp, cb8, ciqt);
3053  Idct(bp3+k, block, width>>1);
3054  }
3055  }
3056  bp += width<<4;
3057  bp1 += width<<4;
3058  bp2 += width<<2;
3059  bp3 += width<<2;
3060  }
3061 #ifdef MMX
3062  emms();
3063 #endif
3064 }
3065 
3066 inline void RTjpeg::decompress8(int8_t *sp, uint8_t **planes)
3067 {
3068  uint8_t * bp = planes[0];
3069  int i, j;
3070 
3071 #ifdef MMX
3072  emms();
3073 #endif
3074 
3075 /* Y */
3076  for(i=0; i<height; i+=8)
3077  {
3078  for(j=0; j<width; j+=8)
3079  if (*sp==-1)sp++;
3080  else
3081  {
3082  sp += s2b(block, sp, lb8, liqt);
3083  Idct(bp+j, block, width);
3084  }
3085  bp += width<<3;
3086  }
3087 }
3088 
3089 #ifdef MMX
3090 
3091 int RTjpeg::bcomp(int16_t *rblock, int16_t *_old, mmx_t *mask)
3092 {
3093  int i;
3094  mmx_t *mold=(mmx_t *)_old;
3095  mmx_t *mblock=(mmx_t *)rblock;
3096  volatile mmx_t result;
3097  static mmx_t neg= { 0xffffffffffffffffULL };
3098 
3099  movq_m2r(*mask, mm7);
3100  movq_m2r(neg, mm6);
3101  pxor_r2r(mm5, mm5);
3102 
3103  for(i=0; i<8; i++)
3104  {
3105  movq_m2r(*(mblock++), mm0);
3106  movq_m2r(*(mblock++), mm2);
3107  movq_m2r(*(mold++), mm1);
3108  movq_m2r(*(mold++), mm3);
3109  psubsw_r2r(mm1, mm0);
3110  psubsw_r2r(mm3, mm2);
3111  movq_r2r(mm0, mm1);
3112  movq_r2r(mm2, mm3);
3113  pcmpgtw_r2r(mm7, mm0);
3114  pcmpgtw_r2r(mm7, mm2);
3115  pxor_r2r(mm6, mm1);
3116  pxor_r2r(mm6, mm3);
3117  pcmpgtw_r2r(mm7, mm1);
3118  pcmpgtw_r2r(mm7, mm3);
3119  por_r2r(mm0, mm5);
3120  por_r2r(mm2, mm5);
3121  por_r2r(mm1, mm5);
3122  por_r2r(mm3, mm5);
3123  }
3124  movq_r2m(mm5, result);
3125 
3126  if (result.q)
3127  {
3128  for(i=0; i<16; i++)((uint64_t *)_old)[i]=((uint64_t *)rblock)[i];
3129  return 0;
3130  }
3131  return 1;
3132 }
3133 
3134 #else
3135 int RTjpeg::bcomp(int16_t *rblock, int16_t *_old, uint16_t *mask)
3136 {
3137  int i;
3138 
3139  for(i=0; i<64; i++)
3140  if (abs(_old[i]-rblock[i])>*mask)
3141  {
3142  for(i=0; i<16; i++)((uint64_t *)_old)[i]=((uint64_t *)rblock)[i];
3143  return 0;
3144  }
3145  return 1;
3146 }
3147 #endif
3148 
3149 inline int RTjpeg::mcompressYUV420(int8_t *sp, uint8_t **planes)
3150 {
3151  int8_t * sb;
3152  int16_t * lblock;
3153  uint8_t * bp = planes[0];
3154  uint8_t * bp1 = bp + (width<<3);
3155  uint8_t * bp2 = planes[1];
3156  uint8_t * bp3 = planes[2];
3157  int i, j, k;
3158 
3159  sb = sp;
3160  lblock = old;
3161 /* Y */
3162  for(i = height>>1; i; i-=8)
3163  {
3164  for(j=0, k=0; j < width; j+=16, k+=8)
3165  {
3166  DctY(bp+j, Ywidth);
3167  Quant(block, lqt);
3168  if (bcomp(block, lblock, &lmask))
3169  {
3170  *((uint8_t *)sp++)=255;
3171  }
3172  else sp+=b2s(block, sp, lb8);
3173  lblock += 64;
3174 
3175  DctY(bp+j+8, Ywidth);
3176  Quant(block, lqt);
3177  if (bcomp(block, lblock, &lmask))
3178  {
3179  *((uint8_t *)sp++)=255;
3180  }
3181  else sp += b2s(block, sp, lb8);
3182  lblock += 64;
3183 
3184  DctY(bp1+j, Ywidth);
3185  Quant(block, lqt);
3186  if (bcomp(block, lblock, &lmask))
3187  {
3188  *((uint8_t *)sp++)=255;
3189  }
3190  else sp += b2s(block, sp, lb8);
3191  lblock += 64;
3192 
3193  DctY(bp1+j+8, Ywidth);
3194  Quant(block, lqt);
3195  if (bcomp(block, lblock, &lmask))
3196  {
3197  *((uint8_t *)sp++)=255;
3198  }
3199  else sp += b2s(block, sp, lb8);
3200  lblock += 64;
3201 
3202  DctY(bp2+k, Cwidth);
3203  Quant(block, cqt);
3204  if (bcomp(block, lblock, &cmask))
3205  {
3206  *((uint8_t *)sp++)=255;
3207  }
3208  else
3209  sp+=b2s(block, sp, cb8);
3210  lblock+=64;
3211 
3212  DctY(bp3+k, Cwidth);
3213  Quant(block, cqt);
3214  if (bcomp(block, lblock, &cmask))
3215  {
3216  *((uint8_t *)sp++)=255;
3217  }
3218  else
3219  sp+=b2s(block, sp, cb8);
3220  lblock+=64;
3221  }
3222  bp += width<<4;
3223  bp1 += width<<4;
3224  bp2 += width<<2;
3225  bp3 += width<<2;
3226  }
3227 #ifdef MMX
3228  emms();
3229 #endif
3230  return (sp-sb);
3231 }
3232 
3233 
3234 inline int RTjpeg::mcompressYUV422(int8_t *sp, uint8_t **planes)
3235 {
3236  int8_t * sb;
3237  int16_t *lblock;
3238  uint8_t * bp = planes[0];
3239  uint8_t * bp2 = planes[1];
3240  uint8_t * bp3 = planes[2];
3241  int i, j, k;
3242 
3243  sb=sp;
3244  lblock = old;
3245  for(i = height; i; i-=8)
3246  {
3247  for(j=0, k=0; j<width; j+=16, k+=8)
3248  {
3249  DctY(bp+j, Ywidth);
3250  Quant(block, lqt);
3251  if (bcomp(block, lblock, &lmask))
3252  {
3253  *((uint8_t *)sp++)=255;
3254  }
3255  else sp+=b2s(block, sp, lb8);
3256  lblock+=64;
3257 
3258  DctY(bp+j+8, Ywidth);
3259  Quant(block, lqt);
3260  if (bcomp(block, lblock, &lmask))
3261  {
3262  *((uint8_t *)sp++)=255;
3263  }
3264  else sp+=b2s(block, sp, lb8);
3265  lblock+=64;
3266 
3267  DctY(bp2+k, Cwidth);
3268  Quant(block, cqt);
3269  if (bcomp(block, lblock, &cmask))
3270  {
3271  *((uint8_t *)sp++)=255;
3272  }
3273  else sp+=b2s(block, sp, cb8);
3274  lblock+=64;
3275 
3276  DctY(bp3+k, Cwidth);
3277  Quant(block, cqt);
3278  if (bcomp(block, lblock, &cmask))
3279  {
3280  *((uint8_t *)sp++)=255;
3281  }
3282  else sp+=b2s(block, sp, cb8);
3283  lblock+=64;
3284 
3285  }
3286  bp += width<<3;
3287  bp2 += width<<2;
3288  bp3 += width<<2;
3289  }
3290 #ifdef MMX
3291  emms();
3292 #endif
3293  return (sp-sb);
3294 }
3295 
3296 inline int RTjpeg::mcompress8(int8_t *sp, uint8_t **planes)
3297 {
3298  uint8_t * bp = planes[0];
3299  int8_t * sb;
3300  int16_t *lblock;
3301  int i, j;
3302 
3303  sb=sp;
3304  lblock = old;
3305  for(i=0; i<height; i+=8)
3306  {
3307  for(j=0; j<width; j+=8)
3308  {
3309  DctY(bp+j, width);
3310  Quant(block, lqt);
3311  if (bcomp(block, lblock, &lmask))
3312  {
3313  *((uint8_t *)sp++)=255;
3314  } else sp+=b2s(block, sp, lb8);
3315  lblock+=64;
3316  }
3317  bp+=width<<3;
3318  }
3319 #ifdef MMX
3320  emms();
3321 #endif
3322  return (sp-sb);
3323 }
3324 
3326 {
3327  key_count = 0;
3328 }
3329 
3330 int RTjpeg::Compress(int8_t *sp, uint8_t **planes)
3331 {
3333  int ds = 0;
3334 
3335  if (key_rate == 0)
3336  {
3337  switch(f)
3338  {
3339  case RTJ_YUV420: ds = compressYUV420((int8_t*)&(fh->data), planes); break;
3340  case RTJ_YUV422: ds = compressYUV422((int8_t*)&(fh->data), planes); break;
3341  case RTJ_RGB8: ds = compress8((int8_t*)&(fh->data), planes); break;
3342  }
3343  fh->key = 0;
3344  } else {
3345  if (key_count == 0)
3346  memset(old, 0, ((4 * width * height)));
3347  switch(f)
3348  {
3349  case RTJ_YUV420: ds = mcompressYUV420((int8_t*)&(fh->data), planes); break;
3350  case RTJ_YUV422: ds = mcompressYUV422((int8_t*)&(fh->data), planes); break;
3351  case RTJ_RGB8: ds = mcompress8((int8_t*)&(fh->data), planes); break;
3352  }
3353  fh->key = key_count;
3354  if (++key_count > key_rate)
3355  key_count = 0;
3356  }
3357  ds += RTJPEG_HEADER_SIZE;
3358  fh->framesize = RTJPEG_SWAP_WORD(ds);
3363  fh->quality = Q;
3364  return ds;
3365 }
3366 
3367 void RTjpeg::Decompress(int8_t *sp, uint8_t **planes)
3368 {
3370 
3371  if ((RTJPEG_SWAP_HALFWORD(fh->width) != width)||
3373  {
3374  int w = RTJPEG_SWAP_HALFWORD(fh->width);
3375  int h = RTJPEG_SWAP_HALFWORD(fh->height);
3376  SetSize(&w, &h);
3377  }
3378  if (fh->quality != Q)
3379  {
3380  int q = fh->quality;
3381  SetQuality(&q);
3382  }
3383  switch(f)
3384  {
3385  case RTJ_YUV420: decompressYUV420((int8_t*)&(fh->data), planes); break;
3386  case RTJ_YUV422: decompressYUV422((int8_t*)&(fh->data), planes); break;
3387  case RTJ_RGB8: decompress8((int8_t*)&(fh->data), planes); break;
3388  }
3389 }
void decompress8(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:3066
static mmx_t RTjpeg_half
Definition: RTjpegN.cpp:32
#define RL(x)
Definition: RTjpegN.cpp:1525
int mcompressYUV420(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:3149
uint8_t version
Definition: RTjpegN.h:146
#define RTJPEG_SWAP_HALFWORD(a)
Definition: RTjpegN.h:47
int height
Definition: RTjpegN.h:130
stderr
Definition: ttvdb.py:1426
int32_t lb8
Definition: RTjpegN.h:119
int f
Definition: RTjpegN.h:132
void SetNextKey(void)
Definition: RTjpegN.cpp:3325
static mmx_t RTjpeg_C6
Definition: RTjpegN.cpp:34
int key_count
Definition: RTjpegN.h:127
int compressYUV420(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:2827
void decompressYUV420(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:3003
static const unsigned char RTjpeg_ZZ[64]
Definition: RTjpegN.cpp:43
int SetIntra(int *key, int *lm, int *cm)
Definition: RTjpegN.cpp:2750
mmx_t lmask
Definition: RTjpegN.h:134
~RTjpeg()
Definition: RTjpegN.cpp:2822
int Q
Definition: RTjpegN.h:131
int16_t * old
Definition: RTjpegN.h:125
static mmx_t RTjpeg_C4
Definition: RTjpegN.cpp:33
int compressYUV422(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:2880
uint16_t width
Definition: RTjpegN.h:147
int SetSize(const int *w, const int *h)
Definition: RTjpegN.cpp:2714
int key_rate
Definition: RTjpegN.h:140
int32_t Csize
Definition: RTjpegN.h:124
#define FIX_1_414213562
Definition: RTjpegN.cpp:1517
static guint32 * tmp
Definition: goom_core.c:35
void Quant(int16_t *block, int32_t *qtbl)
Definition: RTjpegN.cpp:534
static const unsigned char RTjpeg_lum_quant_tbl[64]
Definition: RTjpegN.cpp:71
#define FIX_2_613125930
Definition: RTjpegN.cpp:1519
#define RTJ_YUV422
Definition: RTjpegN.h:61
int compress8(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:2925
#define RTJ_RGB8
Definition: RTjpegN.h:62
#define RTJ_YUV420
Definition: RTjpegN.h:60
#define RTJPEG_FILE_VERSION
Definition: RTjpegN.h:35
uint16_t height
Definition: RTjpegN.h:148
int Compress(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:3330
static mmx_t RTjpeg_C2mC6
Definition: RTjpegN.cpp:35
static mmx_t RTjpeg_ones
Definition: RTjpegN.cpp:31
int SetFormat(const int *fmt)
Definition: RTjpegN.cpp:2708
int32_t Cwidth
Definition: RTjpegN.h:122
void Idct(uint8_t *odata, int16_t *data, int rskip)
Definition: RTjpegN.cpp:1539
unsigned short uint16_t
Definition: iso6937tables.h:1
RTjpeg()
Definition: RTjpegN.cpp:2794
#define RTJPEG_SWAP_WORD(a)
Definition: RTjpegN.h:46
#define FIX_1_082392200
Definition: RTjpegN.cpp:1516
uint8_t headersize
Definition: RTjpegN.h:145
static const unsigned char RTjpeg_chrom_quant_tbl[64]
Definition: RTjpegN.cpp:82
int mcompressYUV422(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:3234
static const uint64_t RTjpeg_aan_tab[64]
Definition: RTjpegN.cpp:60
int16_t * old_start
Definition: RTjpegN.h:126
void decompressYUV422(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:2954
#define RTJPEG_HEADER_SIZE
Definition: RTjpegN.h:36
#define mmx_t
uint8_t quality
Definition: RTjpegN.h:149
int32_t Ysize
Definition: RTjpegN.h:123
static mmx_t RTjpeg_zero
Definition: RTjpegN.cpp:37
static mmx_t RTjpeg_C2pC6
Definition: RTjpegN.cpp:36
#define emms()
Definition: mm_arch.h:15
int SetQuality(int *quality)
Definition: RTjpegN.cpp:2691
int b2s(const int16_t *data, int8_t *strm, uint8_t bt8)
Definition: RTjpegN.cpp:110
int width
Definition: RTjpegN.h:129
#define DESCALE(x)
Definition: RTjpegN.cpp:1521
uint32_t framesize
Definition: RTjpegN.h:144
void DctInit(void)
Definition: RTjpegN.cpp:598
int32_t cb8
Definition: RTjpegN.h:120
int bcomp(int16_t *rblock, int16_t *old, mmx_t *mask)
Definition: RTjpegN.cpp:3091
#define FIX_1_847759065
Definition: RTjpegN.cpp:1518
int32_t Ywidth
Definition: RTjpegN.h:121
void DctY(uint8_t *idata, int rskip)
Definition: RTjpegN.cpp:609
int s2b(int16_t *data, const int8_t *strm, uint8_t bt8, int32_t *qtbla)
Definition: RTjpegN.cpp:281
void CalcTbls(void)
Definition: RTjpegN.cpp:2657
void IdctInit(void)
Definition: RTjpegN.cpp:1528
void QuantInit(void)
Definition: RTjpegN.cpp:518
#define MULTIPLY(var, const)
Definition: RTjpegN.cpp:1526
void Decompress(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:3367
int mcompress8(int8_t *sp, uint8_t **planes)
Definition: RTjpegN.cpp:3296
mmx_t cmask
Definition: RTjpegN.h:135