[cvs] / xvidcore / src / image / image.c Repository:
ViewVC logotype

Diff of /xvidcore/src/image/image.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.20.2.13, Sun Dec 29 06:48:25 2002 UTC revision 1.21, Fri Sep 6 17:37:07 2002 UTC
# Line 1  Line 1 
1  /**************************************************************************  /*****************************************************************************
2   *   *
3   *      XVID MPEG-4 VIDEO CODEC   *      XVID MPEG-4 VIDEO CODEC
4   *      image stuff   *  - image module -
5     *
6     *  Copyright(C) 2002 Peter Ross <pross@xvid.org>
7   *   *
8   *      This program is an implementation of a part of one or more MPEG-4   *      This program is an implementation of a part of one or more MPEG-4
9   *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending   *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
# Line 24  Line 26 
26   *   *
27   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
28   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
29   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
30   *   *
31   *************************************************************************/   ****************************************************************************/
   
 /**************************************************************************  
  *  
  *      History:  
  *  
  *  05.10.2002  support for interpolated images in qpel mode - Isibaar  
  *      01.05.2002      BFRAME image-based u,v interpolation  
  *  22.04.2002  added some B-frame support  
  *      14.04.2002      added image_dump_yuvpgm(), added image_mad()  
  *              XVID_CSP_USER input support  
  *  09.04.2002  PSNR calculations - Isibaar  
  *      06.04.2002      removed interlaced edging from U,V blocks (as per spec)  
  *  26.03.2002  interlacing support (field-based edging in set_edges)  
  *      26.01.2002      rgb555, rgb565  
  *      07.01.2001      commented u,v interpolation (not required for uv-block-based)  
  *  23.12.2001  removed #ifdefs, added function pointers + init_common()  
  *      22.12.2001      cpu #ifdefs  
  *  19.12.2001  image_dump(); useful for debugging  
  *       6.12.2001      inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>  
  *  
  *************************************************************************/  
32    
33  #include <stdlib.h>  #include <stdlib.h>
34  #include <string.h>                             // memcpy, memset  #include <string.h>                             // memcpy, memset
35  #include <math.h>  #include <math.h>
36    
37  #include "../portab.h"  #include "../portab.h"
 #include "../global.h"                  // XVID_CSP_XXX's  
38  #include "../xvid.h"                    // XVID_CSP_XXX's  #include "../xvid.h"                    // XVID_CSP_XXX's
39  #include "image.h"  #include "image.h"
40  #include "colorspace.h"  #include "colorspace.h"
41  #include "interpolate8x8.h"  #include "interpolate8x8.h"
 #include "reduced.h"  
42  #include "../divx4.h"  #include "../divx4.h"
43  #include "../utils/mem_align.h"  #include "../utils/mem_align.h"
44    
 #include "font.h"               // XXX: remove later  
   
45  #define SAFETY  64  #define SAFETY  64
46  #define EDGE_SIZE2  (EDGE_SIZE/2)  #define EDGE_SIZE2  (EDGE_SIZE/2)
47    
# Line 165  Line 142 
142                             uint32_t edged_width,                             uint32_t edged_width,
143                             uint32_t edged_height,                             uint32_t edged_height,
144                             uint32_t width,                             uint32_t width,
145                             uint32_t height)                             uint32_t height,
146                               uint32_t interlacing)
147  {  {
148          const uint32_t edged_width2 = edged_width / 2;          const uint32_t edged_width2 = edged_width / 2;
149          const uint32_t width2 = width / 2;          const uint32_t width2 = width / 2;
# Line 178  Line 156 
156          src = image->y;          src = image->y;
157    
158          for (i = 0; i < EDGE_SIZE; i++) {          for (i = 0; i < EDGE_SIZE; i++) {
159    /*              // if interlacing, edges contain top-most data from each field
160                    if (interlacing && (i & 1)) {
161                            memset(dst, *(src + edged_width), EDGE_SIZE);
162                            memcpy(dst + EDGE_SIZE, src + edged_width, width);
163                            memset(dst + edged_width - EDGE_SIZE,
164                                       *(src + edged_width + width - 1), EDGE_SIZE);
165                    } else {*/
166                  memset(dst, *src, EDGE_SIZE);                  memset(dst, *src, EDGE_SIZE);
167                  memcpy(dst + EDGE_SIZE, src, width);                  memcpy(dst + EDGE_SIZE, src, width);
168                  memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),                  memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),
169                             EDGE_SIZE);                             EDGE_SIZE);
170                    /*}*/
171                  dst += edged_width;                  dst += edged_width;
172          }          }
173    
# Line 194  Line 180 
180    
181          src -= edged_width;          src -= edged_width;
182          for (i = 0; i < EDGE_SIZE; i++) {          for (i = 0; i < EDGE_SIZE; i++) {
183    /*              // if interlacing, edges contain bottom-most data from each field
184                    if (interlacing && !(i & 1)) {
185                            memset(dst, *(src - edged_width), EDGE_SIZE);
186                            memcpy(dst + EDGE_SIZE, src - edged_width, width);
187                            memset(dst + edged_width - EDGE_SIZE,
188                                       *(src - edged_width + width - 1), EDGE_SIZE);
189                    } else {*/
190                  memset(dst, *src, EDGE_SIZE);                  memset(dst, *src, EDGE_SIZE);
191                  memcpy(dst + EDGE_SIZE, src, width);                  memcpy(dst + EDGE_SIZE, src, width);
192                  memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),                  memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),
193                                     EDGE_SIZE);                                     EDGE_SIZE);
194                    /*}*/
195                  dst += edged_width;                  dst += edged_width;
196          }          }
197    
# Line 266  Line 260 
260                                    IMAGE * refhv,                                    IMAGE * refhv,
261                                    uint32_t edged_width,                                    uint32_t edged_width,
262                                    uint32_t edged_height,                                    uint32_t edged_height,
                                   uint32_t quarterpel,  
263                                    uint32_t rounding)                                    uint32_t rounding)
264  {  {
265          const uint32_t offset = EDGE_SIZE2 * (edged_width + 1); // we only interpolate half of the edge area          const uint32_t offset = EDGE_SIZE * (edged_width + 1);
266          const uint32_t stride_add = 7 * edged_width;          const uint32_t stride_add = 7 * edged_width;
267  /*  
268  #ifdef BFRAMES  #ifdef BFRAMES
269          const uint32_t edged_width2 = edged_width / 2;          const uint32_t edged_width2 = edged_width / 2;
270          const uint32_t edged_height2 = edged_height / 2;          const uint32_t edged_height2 = edged_height / 2;
271          const uint32_t offset2 = EDGE_SIZE2 * (edged_width2 + 1);          const uint32_t offset2 = EDGE_SIZE2 * (edged_width2 + 1);
272          const uint32_t stride_add2 = 7 * edged_width2;          const uint32_t stride_add2 = 7 * edged_width2;
273  #endif  #endif
274  */  
275          uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr;          uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr;
276          uint32_t x, y;          uint32_t x, y;
277    
# Line 293  Line 286 
286          v_ptr -= offset;          v_ptr -= offset;
287          hv_ptr -= offset;          hv_ptr -= offset;
288    
289          if(quarterpel) {          for (y = 0; y < edged_height; y = y + 8) {
290                    for (x = 0; x < edged_width; x = x + 8) {
                 for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) {  
                         for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) {  
                                 interpolate8x8_6tap_lowpass_h(h_ptr, n_ptr, edged_width, rounding);  
                                 interpolate8x8_6tap_lowpass_v(v_ptr, n_ptr, edged_width, rounding);  
   
                                 n_ptr += 8;  
                                 h_ptr += 8;  
                                 v_ptr += 8;  
                         }  
   
                         n_ptr += EDGE_SIZE;  
                         h_ptr += EDGE_SIZE;  
                         v_ptr += EDGE_SIZE;  
   
                         h_ptr += stride_add;  
                         v_ptr += stride_add;  
                         n_ptr += stride_add;  
                 }  
   
                 h_ptr = refh->y;  
                 h_ptr -= offset;  
   
                 for (y = 0; y < (edged_height - EDGE_SIZE); y = y + 8) {  
                         for (x = 0; x < (edged_width - EDGE_SIZE); x = x + 8) {  
                                 interpolate8x8_6tap_lowpass_v(hv_ptr, h_ptr, edged_width, rounding);  
                                 hv_ptr += 8;  
                                 h_ptr += 8;  
                         }  
   
                         hv_ptr += EDGE_SIZE;  
                         h_ptr += EDGE_SIZE;  
   
                         hv_ptr += stride_add;  
                         h_ptr += stride_add;  
                 }  
         }  
         else {  
   
                 for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) {  
                         for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) {  
291                                  interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding);                                  interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding);
292                                  interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding);                                  interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding);
293                                  interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding);                                  interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding);
# Line 344  Line 297 
297                                  v_ptr += 8;                                  v_ptr += 8;
298                                  hv_ptr += 8;                                  hv_ptr += 8;
299                          }                          }
   
                         h_ptr += EDGE_SIZE;  
                         v_ptr += EDGE_SIZE;  
                         hv_ptr += EDGE_SIZE;  
                         n_ptr += EDGE_SIZE;  
   
300                          h_ptr += stride_add;                          h_ptr += stride_add;
301                          v_ptr += stride_add;                          v_ptr += stride_add;
302                          hv_ptr += stride_add;                          hv_ptr += stride_add;
303                          n_ptr += stride_add;                          n_ptr += stride_add;
304                  }                  }
305          }  
 /*  
306  #ifdef BFRAMES  #ifdef BFRAMES
307          n_ptr = refn->u;          n_ptr = refn->u;
308          h_ptr = refh->u;          h_ptr = refh->u;
# Line 368  Line 314 
314          v_ptr -= offset2;          v_ptr -= offset2;
315          hv_ptr -= offset2;          hv_ptr -= offset2;
316    
317          for (y = 0; y < edged_height2; y += 8) {          for (y = 0; y < edged_height2; y = y + 8) {
318                  for (x = 0; x < edged_width2; x += 8) {                  for (x = 0; x < edged_width2; x = x + 8) {
319                          interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);                          interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);
320                          interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);                          interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);
321                          interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);                          interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);
# Line 412  Line 358 
358                  n_ptr += stride_add2;                  n_ptr += stride_add2;
359          }          }
360  #endif  #endif
361  */  
362          /*          /*
363             interpolate_halfpel_h(             interpolate_halfpel_h(
364             refh->y - offset,             refh->y - offset,
# Line 476  Line 422 
422  }  }
423    
424    
 /*  
 chroma optimize filter, invented by mf  
 a chroma pixel is average from the surrounding pixels, when the  
 correpsonding luma pixels are pure black or white.  
 */  
   
 void  
 image_chroma_optimize(IMAGE * img, int width, int height, int edged_width)  
 {  
         int x,y;  
         int pixels = 0;  
   
         for (y = 1; y < height/2 - 1; y++)  
         for (x = 1; x < width/2 - 1; x++)  
         {  
 #define IS_PURE(a)  ((a)<=16||(a)>=235)  
 #define IMG_Y(Y,X)      img->y[(Y)*edged_width + (X)]  
 #define IMG_U(Y,X)      img->u[(Y)*edged_width/2 + (X)]  
 #define IMG_V(Y,X)      img->v[(Y)*edged_width/2 + (X)]  
   
                 if (IS_PURE(IMG_Y(y*2  ,x*2  )) &&  
                         IS_PURE(IMG_Y(y*2  ,x*2+1)) &&  
                         IS_PURE(IMG_Y(y*2+1,x*2  )) &&  
                         IS_PURE(IMG_Y(y*2+1,x*2+1)))  
                 {  
                         IMG_U(y,x) = (IMG_U(y,x-1) + IMG_U(y-1, x) + IMG_U(y, x+1) + IMG_U(y+1, x)) / 4;  
                         IMG_V(y,x) = (IMG_V(y,x-1) + IMG_V(y-1, x) + IMG_V(y, x+1) + IMG_V(y+1, x)) / 4;  
                         pixels++;  
                 }  
   
 #undef IS_PURE  
 #undef IMG_Y  
 #undef IMG_U  
 #undef IMG_V  
         }  
   
         DPRINTF(DPRINTF_DEBUG,"chroma_optimized_pixels = %i/%i", pixels, width*height/4);  
 }  
   
   
   
   
   
 /*  
   perform safe packed colorspace conversion, by splitting  
   the image up into an optimized area (pixel width divisible by 16),  
   and two unoptimized/plain-c areas (pixel width divisible by 2)  
 */  
   
 static void  
 safe_packed_conv(uint8_t * x_ptr, int x_stride,  
                                  uint8_t * y_ptr, uint8_t * u_ptr, uint8_t * v_ptr,  
                                  int y_stride, int uv_stride,  
                                  int width, int height, int vflip,  
                                  packedFunc * func_opt, packedFunc func_c, int size)  
 {  
         int width_opt, width_c;  
   
         if (func_opt != func_c && x_stride < size*((width+15)/16)*16)  
         {  
                 width_opt = width & (~15);  
                 width_c = width - width_opt;  
         }  
         else  
         {  
                 width_opt = width;  
                 width_c = 0;  
         }  
   
         func_opt(x_ptr, x_stride,  
                         y_ptr, u_ptr, v_ptr, y_stride, uv_stride,  
                         width_opt, height, vflip);  
   
         if (width_c)  
         {  
                 func_c(x_ptr + size*width_opt, x_stride,  
                         y_ptr + width_opt, u_ptr + width_opt/2, v_ptr + width_opt/2,  
                         y_stride, uv_stride, width_c, height, vflip);  
         }  
 }  
   
   
   
425  int  int
426  image_input(IMAGE * image,  image_input(IMAGE * image,
427                          uint32_t width,                          uint32_t width,
428                          int height,                          int height,
429                          uint32_t edged_width,                          uint32_t edged_width,
430                          uint8_t * src,                          uint8_t * src,
431                          int src_stride,                          int csp)
                         int csp,  
                         int interlacing)  
432  {  {
         const int edged_width2 = edged_width/2;  
         const int width2 = width/2;  
         const int height2 = height/2;  
         //const int height_signed = (csp & XVID_CSP_VFLIP) ? -height : height;  
   
   
         //      int src_stride = width;  
433    
434          // --- xvid 2.1 compatiblity patch ---  /*      if (csp & XVID_CSP_VFLIP)
         // --- remove when xvid_dec_frame->stride equals real stride  
         /*  
         if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB555 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB565 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YUY2 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YVYU ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_UYVY)  
         {  
                 src_stride *= 2;  
         }  
         else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24)  
435          {          {
436                  src_stride *= 3;                  height = -height;
         }  
         else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA)  
         {  
                 src_stride *= 4;  
437          }          }
438          */          */
         // ^--- xvid 2.1 compatiblity fix ---^  
439    
440          switch (csp & ~XVID_CSP_VFLIP) {          switch (csp & ~XVID_CSP_VFLIP) {
441          case XVID_CSP_RGB555:          case XVID_CSP_RGB555:
442                  safe_packed_conv(                  rgb555_to_yv12(image->y, image->u, image->v, src, width, height,
443                          src, src_stride, image->y, image->u, image->v,                                             edged_width);
444                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?rgb555i_to_yv12  :rgb555_to_yv12,  
                         interlacing?rgb555i_to_yv12_c:rgb555_to_yv12_c, 2);  
                 break;  
445    
446          case XVID_CSP_RGB565:          case XVID_CSP_RGB565:
447                  safe_packed_conv(                  rgb565_to_yv12(image->y, image->u, image->v, src, width, height,
448                          src, src_stride, image->y, image->u, image->v,                                             edged_width);
449                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?rgb565i_to_yv12  :rgb565_to_yv12,  
                         interlacing?rgb565i_to_yv12_c:rgb565_to_yv12_c, 2);  
                 break;  
450    
451    
452          case XVID_CSP_RGB24:          case XVID_CSP_RGB24:
453                  safe_packed_conv(                  rgb24_to_yv12(image->y, image->u, image->v, src, width, height,
454                          src, src_stride, image->y, image->u, image->v,                                            edged_width);
455                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?bgri_to_yv12  :bgr_to_yv12,  
                         interlacing?bgri_to_yv12_c:bgr_to_yv12_c, 3);  
                 break;  
456    
457          case XVID_CSP_RGB32:          case XVID_CSP_RGB32:
458                  safe_packed_conv(                  rgb32_to_yv12(image->y, image->u, image->v, src, width, height,
459                          src, src_stride, image->y, image->u, image->v,                                            edged_width);
460                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?bgrai_to_yv12  :bgra_to_yv12,  
                         interlacing?bgrai_to_yv12_c:bgra_to_yv12_c, 4);  
                 break;  
461    
462          case XVID_CSP_ABGR :          case XVID_CSP_I420:
463                  safe_packed_conv(                  yuv_to_yv12(image->y, image->u, image->v, src, width, height,
464                          src, src_stride, image->y, image->u, image->v,                                          edged_width);
465                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?abgri_to_yv12  :abgr_to_yv12,  
                         interlacing?abgri_to_yv12_c:abgr_to_yv12_c, 4);  
                 break;  
466    
467          case XVID_CSP_RGBA :          case XVID_CSP_YV12:             /* u/v swapped */
468                  safe_packed_conv(                  yuv_to_yv12(image->y, image->v, image->u, src, width, height,
469                          src, src_stride, image->y, image->u, image->v,                                          edged_width);
470                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?rgbai_to_yv12  :rgba_to_yv12,  
                         interlacing?rgbai_to_yv12_c:rgba_to_yv12_c, 4);  
                 break;  
471    
472          case XVID_CSP_YUY2:          case XVID_CSP_YUY2:
473                  safe_packed_conv(                  yuyv_to_yv12(image->y, image->u, image->v, src, width, height,
474                          src, src_stride, image->y, image->u, image->v,                                           edged_width);
475                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?yuyvi_to_yv12  :yuyv_to_yv12,  
                         interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2);  
                 break;  
476    
477          case XVID_CSP_YVYU:             /* u/v swapped */          case XVID_CSP_YVYU:             /* u/v swapped */
478                  safe_packed_conv(                  yuyv_to_yv12(image->y, image->v, image->u, src, width, height,
479                          src, src_stride, image->y, image->v, image->y,                                           edged_width);
480                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?yuyvi_to_yv12  :yuyv_to_yv12,  
                         interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2);  
                 break;  
481    
482          case XVID_CSP_UYVY:          case XVID_CSP_UYVY:
483                  safe_packed_conv(                  uyvy_to_yv12(image->y, image->u, image->v, src, width, height,
484                          src, src_stride, image->y, image->u, image->v,                                           edged_width);
485                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),                  return 0;
                         interlacing?uyvyi_to_yv12  :uyvy_to_yv12,  
                         interlacing?uyvyi_to_yv12_c:uyvy_to_yv12_c, 2);  
                 break;  
   
         case XVID_CSP_I420:  
                 yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2,  
                         src, src + src_stride*height, src + src_stride*height + (src_stride/2)*height2,  
                         src_stride, src_stride/2, width, height, (csp & XVID_CSP_VFLIP));  
                 break  
                         ;  
         case XVID_CSP_YV12:             /* u/v swapped */  
                 yv12_to_yv12(image->y, image->v, image->u, edged_width, edged_width2,  
                         src, src + src_stride*height, src + src_stride*height + (src_stride/2)*height2,  
                         src_stride, src_stride/2, width, height, (csp & XVID_CSP_VFLIP));  
                 break;  
486    
487          case XVID_CSP_USER:          case XVID_CSP_USER:
488                  {                  user_to_yuv_c(image->y, image->u, image->v, edged_width,
489                          DEC_PICTURE * pic = (DEC_PICTURE*)src;                                            (DEC_PICTURE *) src, width, height);
490                          yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2,                  return 0;
                                 pic->y, pic->u, pic->v, pic->stride_y, pic->stride_y,  
                                 width, height, (csp & XVID_CSP_VFLIP));  
                 }  
                 break;  
491    
492          case XVID_CSP_NULL:          case XVID_CSP_NULL:
493                  break;                  break;
494    
         default :  
                 return -1;  
         }  
   
   
         /* pad out image when the width and/or height is not a multiple of 16 */  
   
         if (width & 15)  
         {  
                 int i;  
                 int pad_width = 16 - (width&15);  
                 for (i = 0; i < height; i++)  
                 {  
                         memset(image->y + i*edged_width + width,  
                                  *(image->y + i*edged_width + width - 1), pad_width);  
                 }  
                 for (i = 0; i < height/2; i++)  
                 {  
                         memset(image->u + i*edged_width2 + width2,  
                                  *(image->u + i*edged_width2 + width2 - 1),pad_width/2);  
                         memset(image->v + i*edged_width2 + width2,  
                                  *(image->v + i*edged_width2 + width2 - 1),pad_width/2);  
                 }  
         }  
   
         if (height & 15)  
         {  
                 int pad_height = 16 - (height&15);  
                 int length = ((width+15)/16)*16;  
                 int i;  
                 for (i = 0; i < pad_height; i++)  
                 {  
                         memcpy(image->y + (height+i)*edged_width,  
                                    image->y + (height-1)*edged_width,length);  
                 }  
   
                 for (i = 0; i < pad_height/2; i++)  
                 {  
                         memcpy(image->u + (height2+i)*edged_width2,  
                                    image->u + (height2-1)*edged_width2,length/2);  
                         memcpy(image->v + (height2+i)*edged_width2,  
                                    image->v + (height2-1)*edged_width2,length/2);  
                 }  
495          }          }
496    
497  /*          return -1;
         if (interlacing)  
                 image_printf(image, edged_width, height, 5,5, "[i]");  
         image_dump_yuvpgm(image, edged_width, ((width+15)/16)*16, ((height+15)/16)*16, "\\encode.pgm");  
 */  
         return 0;  
498  }  }
499    
500    
# Line 761  Line 506 
506                           uint32_t edged_width,                           uint32_t edged_width,
507                           uint8_t * dst,                           uint8_t * dst,
508                           uint32_t dst_stride,                           uint32_t dst_stride,
509                           int csp,                           int csp)
                          int interlacing)  
 {  
         const int edged_width2 = edged_width/2;  
         int height2 = height/2;  
   
 /*  
         if (interlacing)  
                 image_printf(image, edged_width, height, 5,100, "[i]=%i,%i",width,height);  
         image_dump_yuvpgm(image, edged_width, width, height, "\\decode.pgm");  
 */  
   
   
         // --- xvid 2.1 compatiblity patch ---  
         // --- remove when xvid_dec_frame->stride equals real stride  
         /*  
         if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB555 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB565 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YUY2 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YVYU ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_UYVY)  
         {  
                 dst_stride *= 2;  
         }  
         else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24)  
510          {          {
511                  dst_stride *= 3;          if (csp & XVID_CSP_VFLIP) {
512                    height = -height;
513          }          }
         else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA)  
         {  
                 dst_stride *= 4;  
         }  
         */  
         // ^--- xvid 2.1 compatiblity fix ---^  
   
514    
515          switch (csp & ~XVID_CSP_VFLIP) {          switch (csp & ~XVID_CSP_VFLIP) {
516          case XVID_CSP_RGB555:          case XVID_CSP_RGB555:
517                  safe_packed_conv(                  yv12_to_rgb555(dst, dst_stride, image->y, image->u, image->v,
518                          dst, dst_stride, image->y, image->u, image->v,                                             edged_width, edged_width / 2, width, height);
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_rgb555i  :yv12_to_rgb555,  
                         interlacing?yv12_to_rgb555i_c:yv12_to_rgb555_c, 2);  
519                  return 0;                  return 0;
520    
521          case XVID_CSP_RGB565:          case XVID_CSP_RGB565:
522                  safe_packed_conv(                  yv12_to_rgb565(dst, dst_stride, image->y, image->u, image->v,
523                          dst, dst_stride, image->y, image->u, image->v,                                             edged_width, edged_width / 2, width, height);
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_rgb565i  :yv12_to_rgb565,  
                         interlacing?yv12_to_rgb565i_c:yv12_to_rgb565_c, 2);  
524                  return 0;                  return 0;
525    
526          case XVID_CSP_RGB24:          case XVID_CSP_RGB24:
527                  safe_packed_conv(                  yv12_to_rgb24(dst, dst_stride, image->y, image->u, image->v,
528                          dst, dst_stride, image->y, image->u, image->v,                                            edged_width, edged_width / 2, width, height);
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_bgri  :yv12_to_bgr,  
                         interlacing?yv12_to_bgri_c:yv12_to_bgr_c, 3);  
529                  return 0;                  return 0;
530    
531          case XVID_CSP_RGB32:          case XVID_CSP_RGB32:
532                  safe_packed_conv(                  yv12_to_rgb32(dst, dst_stride, image->y, image->u, image->v,
533                          dst, dst_stride, image->y, image->u, image->v,                                            edged_width, edged_width / 2, width, height);
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_bgrai  :yv12_to_bgra,  
                         interlacing?yv12_to_bgrai_c:yv12_to_bgra_c, 4);  
                 return 0;  
   
         case XVID_CSP_ABGR:  
                 safe_packed_conv(  
                         dst, dst_stride, image->y, image->u, image->v,  
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_abgri  :yv12_to_abgr,  
                         interlacing?yv12_to_abgri_c:yv12_to_abgr_c, 4);  
                 return 0;  
   
         case XVID_CSP_RGBA:  
                 safe_packed_conv(  
                         dst, dst_stride, image->y, image->u, image->v,  
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_rgbai  :yv12_to_rgba,  
                         interlacing?yv12_to_rgbai_c:yv12_to_rgba_c, 4);  
534                  return 0;                  return 0;
535    
536          case XVID_CSP_YUY2:          case XVID_CSP_I420:
537                  safe_packed_conv(                  yv12_to_yuv(dst, dst_stride, image->y, image->u, image->v, edged_width,
538                          dst, dst_stride, image->y, image->u, image->v,                                          edged_width / 2, width, height);
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_yuyvi  :yv12_to_yuyv,  
                         interlacing?yv12_to_yuyvi_c:yv12_to_yuyv_c, 2);  
539                  return 0;                  return 0;
540    
541          case XVID_CSP_YVYU:             // u,v swapped          case XVID_CSP_YV12:             // u,v swapped
542                  safe_packed_conv(                  yv12_to_yuv(dst, dst_stride, image->y, image->v, image->u, edged_width,
543                          dst, dst_stride, image->y, image->v, image->u,                                          edged_width / 2, width, height);
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_yuyvi  :yv12_to_yuyv,  
                         interlacing?yv12_to_yuyvi_c:yv12_to_yuyv_c, 2);  
544                  return 0;                  return 0;
545    
546          case XVID_CSP_UYVY:          case XVID_CSP_YUY2:
547                  safe_packed_conv(                  yv12_to_yuyv(dst, dst_stride, image->y, image->u, image->v,
548                          dst, dst_stride, image->y, image->u, image->v,                                           edged_width, edged_width / 2, width, height);
                         edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),  
                         interlacing?yv12_to_uyvyi  :yv12_to_uyvy,  
                         interlacing?yv12_to_uyvyi_c:yv12_to_uyvy_c, 2);  
549                  return 0;                  return 0;
550    
551          case XVID_CSP_I420:          case XVID_CSP_YVYU:             // u,v swapped
552                  yv12_to_yv12(dst, dst + dst_stride*height, dst + dst_stride*height + (dst_stride/2)*height2,                  yv12_to_yuyv(dst, dst_stride, image->y, image->v, image->u,
553                          dst_stride, dst_stride/2,                                           edged_width, edged_width / 2, width, height);
                         image->y, image->u, image->v, edged_width, edged_width2,  
                         width, height, (csp & XVID_CSP_VFLIP));  
554                  return 0;                  return 0;
555    
556          case XVID_CSP_YV12:             // u,v swapped          case XVID_CSP_UYVY:
557                  yv12_to_yv12(dst, dst + dst_stride*height, dst + dst_stride*height + (dst_stride/2)*height2,                  yv12_to_uyvy(dst, dst_stride, image->y, image->u, image->v,
558                          dst_stride, dst_stride/2,                                           edged_width, edged_width / 2, width, height);
                         image->y, image->v, image->u, edged_width, edged_width2,  
                         width, height, (csp & XVID_CSP_VFLIP));  
559                  return 0;                  return 0;
560    
561          case XVID_CSP_USER:          case XVID_CSP_USER:
562                  {                  ((DEC_PICTURE *) dst)->y = image->y;
563                          DEC_PICTURE * pic = (DEC_PICTURE*)dst;                  ((DEC_PICTURE *) dst)->u = image->u;
564                          pic->y = image->y;                  ((DEC_PICTURE *) dst)->v = image->v;
565                          pic->u = image->u;                  ((DEC_PICTURE *) dst)->stride_y = edged_width;
566                          pic->v = image->v;                  ((DEC_PICTURE *) dst)->stride_uv = edged_width / 2;
                         pic->stride_y = edged_width;  
                         pic->stride_uv = edged_width / 2;  
                 }  
567                  return 0;                  return 0;
568    
569          case XVID_CSP_NULL:          case XVID_CSP_NULL:
# Line 1097  Line 766 
766      sV += std2;      sV += std2;
767    }    }
768  }  }
   
   
 void  
 image_clear(IMAGE * img, int width, int height, int edged_width,  
                                         int y, int u, int v)  
 {  
         uint8_t * p;  
         int i;  
   
         p = img->y;  
         for (i = 0; i < height; i++) {  
                 memset(p, y, width);  
                 p += edged_width;  
         }  
   
         p = img->u;  
         for (i = 0; i < height/2; i++) {  
                 memset(p, u, width/2);  
                 p += edged_width/2;  
         }  
   
         p = img->v;  
         for (i = 0; i < height/2; i++) {  
                 memset(p, v, width/2);  
                 p += edged_width/2;  
         }  
 }  
   
   
 /* reduced resolution deblocking filter  
         block = block size (16=rrv, 8=full resolution)  
         flags = XVID_DEC_YDEBLOCK|XVID_DEC_UVDEBLOCK  
 */  
 void  
 image_deblock_rrv(IMAGE * img, int edged_width,  
                                 const MACROBLOCK * mbs, int mb_width, int mb_height, int mb_stride,  
                                 int block, int flags)  
 {  
         const int edged_width2 = edged_width /2;  
         const int nblocks = block / 8;  /* skals code uses 8pixel block uints */  
         int i,j;  
   
         /* luma: j,i in block units */  
         if ((flags & XVID_DEC_DEBLOCKY))  
         {  
                 for (j = 1; j < mb_height*2; j++)               /* horizontal deblocking */  
                 for (i = 0; i < mb_width*2; i++)  
                 {  
                         if (mbs[(j-1)/2*mb_stride + (i/2)].mode != MODE_NOT_CODED ||  
                                 mbs[(j+0)/2*mb_stride + (i/2)].mode != MODE_NOT_CODED)  
                         {  
                                 hfilter_31(img->y + (j*block - 1)*edged_width + i*block,  
                                                                   img->y + (j*block + 0)*edged_width + i*block, nblocks);  
                         }  
                 }  
   
                 for (j = 0; j < mb_height*2; j++)               /* vertical deblocking */  
                 for (i = 1; i < mb_width*2; i++)  
                 {  
                         if (mbs[(j/2)*mb_stride + (i-1)/2].mode != MODE_NOT_CODED ||  
                                 mbs[(j/2)*mb_stride + (i+0)/2].mode != MODE_NOT_CODED)  
                         {  
                                 vfilter_31(img->y + (j*block)*edged_width + i*block - 1,  
                                                    img->y + (j*block)*edged_width + i*block + 0,  
                                                    edged_width, nblocks);  
                         }  
                 }  
         }  
   
   
         /* chroma */  
         if ((flags & XVID_DEC_DEBLOCKUV))  
         {  
                 for (j = 1; j < mb_height; j++)         /* horizontal deblocking */  
                 for (i = 0; i < mb_width; i++)  
                 {  
                         if (mbs[(j-1)*mb_stride + i].mode != MODE_NOT_CODED ||  
                                 mbs[(j+0)*mb_stride + i].mode != MODE_NOT_CODED)  
                         {  
                                 hfilter_31(img->u + (j*block - 1)*edged_width2 + i*block,  
                                                    img->u + (j*block + 0)*edged_width2 + i*block, nblocks);  
                                 hfilter_31(img->v + (j*block - 1)*edged_width2 + i*block,  
                                                    img->v + (j*block + 0)*edged_width2 + i*block, nblocks);  
                         }  
                 }  
   
                 for (j = 0; j < mb_height; j++)         /* vertical deblocking */  
                 for (i = 1; i < mb_width; i++)  
                 {  
                         if (mbs[j*mb_stride + i - 1].mode != MODE_NOT_CODED ||  
                                 mbs[j*mb_stride + i + 0].mode != MODE_NOT_CODED)  
                         {  
                                 vfilter_31(img->u + (j*block)*edged_width2 + i*block - 1,  
                                                    img->u + (j*block)*edged_width2 + i*block + 0,  
                                                    edged_width2, nblocks);  
                                 vfilter_31(img->v + (j*block)*edged_width2 + i*block - 1,  
                                                    img->v + (j*block)*edged_width2 + i*block + 0,  
                                                    edged_width2, nblocks);  
                         }  
                 }  
         }  
   
 }  

Legend:
Removed from v.1.20.2.13  
changed lines
  Added in v.1.21

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4