[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.24, Sun Nov 17 00:20:30 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   *      This program is an implementation of a part of one or more MPEG-4   *  Copyright(C) 2002 Peter Ross <pross@xvid.org>
  *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  
  *      to use this software module in hardware or software products are  
  *      advised that its use may infringe existing patents or copyrights, and  
  *      any such use would be at such party's own risk.  The original  
  *      developer of this software module and his/her company, and subsequent  
  *      editors and their companies, will have no liability for use of this  
  *      software or modifications or derivatives thereof.  
7   *   *
8   *      This program is free software; you can redistribute it and/or modify   *  This file is part of XviD, a free MPEG-4 video encoder/decoder
9   *      it under the terms of the GNU General Public License as published by   *
10     *  XviD is free software; you can redistribute it and/or modify it
11     *  under the terms of the GNU General Public License as published by
12   *      the Free Software Foundation; either version 2 of the License, or   *      the Free Software Foundation; either version 2 of the License, or
13   *      (at your option) any later version.   *      (at your option) any later version.
14   *   *
# Line 24  Line 19 
19   *   *
20   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
21   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
22   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23   *   *
24   *************************************************************************/   *  Under section 8 of the GNU General Public License, the copyright
25     *  holders of XVID explicitly forbid distribution in the following
26  /**************************************************************************   *  countries:
27     *
28     *    - Japan
29     *    - United States of America
30     *
31     *  Linking XviD statically or dynamically with other modules is making a
32     *  combined work based on XviD.  Thus, the terms and conditions of the
33     *  GNU General Public License cover the whole combination.
34   *   *
35   *      History:   *  As a special exception, the copyright holders of XviD give you
36     *  permission to link XviD with independent modules that communicate with
37     *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the
38     *  license terms of these independent modules, and to copy and distribute
39     *  the resulting combined work under terms of your choice, provided that
40     *  every copy of the combined work is accompanied by a complete copy of
41     *  the source code of XviD (the version of XviD used to produce the
42     *  combined work), being distributed under the terms of the GNU General
43     *  Public License plus this exception.  An independent module is a module
44     *  which is not derived from or based on XviD.
45   *   *
46   *  05.10.2002  support for interpolated images in qpel mode - Isibaar   *  Note that people who make modified versions of XviD are not obligated
47   *      01.05.2002      BFRAME image-based u,v interpolation   *  to grant this special exception for their modified versions; it is
48   *  22.04.2002  added some B-frame support   *  their choice whether to do so.  The GNU General Public License gives
49   *      14.04.2002      added image_dump_yuvpgm(), added image_mad()   *  permission to release a modified version without this exception; this
50   *              XVID_CSP_USER input support   *  exception also makes it possible to release a modified version which
51   *  09.04.2002  PSNR calculations - Isibaar   *  carries forward this exception.
  *      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>  
52   *   *
53   *************************************************************************/   * $Id$
54     *
55     ****************************************************************************/
56    
57  #include <stdlib.h>  #include <stdlib.h>
58  #include <string.h>                             // memcpy, memset  #include <string.h>                             // memcpy, memset
59  #include <math.h>  #include <math.h>
60    
61  #include "../portab.h"  #include "../portab.h"
 #include "../global.h"                  // XVID_CSP_XXX's  
62  #include "../xvid.h"                    // XVID_CSP_XXX's  #include "../xvid.h"                    // XVID_CSP_XXX's
63  #include "image.h"  #include "image.h"
64  #include "colorspace.h"  #include "colorspace.h"
65  #include "interpolate8x8.h"  #include "interpolate8x8.h"
 #include "reduced.h"  
66  #include "../divx4.h"  #include "../divx4.h"
67  #include "../utils/mem_align.h"  #include "../utils/mem_align.h"
68    
 #include "font.h"               // XXX: remove later  
   
69  #define SAFETY  64  #define SAFETY  64
70  #define EDGE_SIZE2  (EDGE_SIZE/2)  #define EDGE_SIZE2  (EDGE_SIZE/2)
71    
# Line 266  Line 267 
267                                    IMAGE * refhv,                                    IMAGE * refhv,
268                                    uint32_t edged_width,                                    uint32_t edged_width,
269                                    uint32_t edged_height,                                    uint32_t edged_height,
                                   uint32_t quarterpel,  
270                                    uint32_t rounding)                                    uint32_t rounding)
271  {  {
272          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);
273          const uint32_t stride_add = 7 * edged_width;          const uint32_t stride_add = 7 * edged_width;
274  /*  
 #ifdef BFRAMES  
         const uint32_t edged_width2 = edged_width / 2;  
         const uint32_t edged_height2 = edged_height / 2;  
         const uint32_t offset2 = EDGE_SIZE2 * (edged_width2 + 1);  
         const uint32_t stride_add2 = 7 * edged_width2;  
 #endif  
 */  
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                  }                  }
         }  
 /*  
 #ifdef BFRAMES  
         n_ptr = refn->u;  
         h_ptr = refh->u;  
         v_ptr = refv->u;  
         hv_ptr = refhv->u;  
   
         n_ptr -= offset2;  
         h_ptr -= offset2;  
         v_ptr -= offset2;  
         hv_ptr -= offset2;  
   
         for (y = 0; y < edged_height2; y += 8) {  
                 for (x = 0; x < edged_width2; x += 8) {  
                         interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);  
                         interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);  
                         interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);  
305    
                         n_ptr += 8;  
                         h_ptr += 8;  
                         v_ptr += 8;  
                         hv_ptr += 8;  
                 }  
                 h_ptr += stride_add2;  
                 v_ptr += stride_add2;  
                 hv_ptr += stride_add2;  
                 n_ptr += stride_add2;  
         }  
   
         n_ptr = refn->v;  
         h_ptr = refh->v;  
         v_ptr = refv->v;  
         hv_ptr = refhv->v;  
   
         n_ptr -= offset2;  
         h_ptr -= offset2;  
         v_ptr -= offset2;  
         hv_ptr -= offset2;  
   
         for (y = 0; y < edged_height2; y = y + 8) {  
                 for (x = 0; x < edged_width2; x = x + 8) {  
                         interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);  
                         interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);  
                         interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);  
   
                         n_ptr += 8;  
                         h_ptr += 8;  
                         v_ptr += 8;  
                         hv_ptr += 8;  
                 }  
                 h_ptr += stride_add2;  
                 v_ptr += stride_add2;  
                 hv_ptr += stride_add2;  
                 n_ptr += stride_add2;  
         }  
 #endif  
 */  
306          /*          /*
307             interpolate_halfpel_h(             interpolate_halfpel_h(
308             refh->y - offset,             refh->y - offset,
# Line 476  Line 366 
366  }  }
367    
368    
 /*  
 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);  
         }  
 }  
   
   
   
369  int  int
370  image_input(IMAGE * image,  image_input(IMAGE * image,
371                          uint32_t width,                          uint32_t width,
372                          int height,                          int height,
373                          uint32_t edged_width,                          uint32_t edged_width,
374                          uint8_t * src,                          uint8_t * src,
375                          int src_stride,                          int csp)
                         int csp,  
                         int interlacing)  
376  {  {
         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;  
377    
378    /*      if (csp & XVID_CSP_VFLIP)
         //      int src_stride = width;  
   
         // --- 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)  
         {  
                 src_stride *= 2;  
         }  
         else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24)  
         {  
                 src_stride *= 3;  
         }  
         else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR ||  
                 (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA)  
379          {          {
380                  src_stride *= 4;                  height = -height;
381          }          }
382          */          */
         // ^--- xvid 2.1 compatiblity fix ---^  
383    
384          switch (csp & ~XVID_CSP_VFLIP) {          switch (csp & ~XVID_CSP_VFLIP) {
385          case XVID_CSP_RGB555:          case XVID_CSP_RGB555:
386                  safe_packed_conv(                  rgb555_to_yv12(image->y, image->u, image->v, src, width, height,
387                          src, src_stride, image->y, image->u, image->v,                                             edged_width);
388                          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;  
389    
390          case XVID_CSP_RGB565:          case XVID_CSP_RGB565:
391                  safe_packed_conv(                  rgb565_to_yv12(image->y, image->u, image->v, src, width, height,
392                          src, src_stride, image->y, image->u, image->v,                                             edged_width);
393                          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;  
394    
395    
396          case XVID_CSP_RGB24:          case XVID_CSP_RGB24:
397                  safe_packed_conv(                  rgb24_to_yv12(image->y, image->u, image->v, src, width, height,
398                          src, src_stride, image->y, image->u, image->v,                                            edged_width);
399                          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;  
400    
401          case XVID_CSP_RGB32:          case XVID_CSP_RGB32:
402                  safe_packed_conv(                  rgb32_to_yv12(image->y, image->u, image->v, src, width, height,
403                          src, src_stride, image->y, image->u, image->v,                                            edged_width);
404                          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;  
405    
406          case XVID_CSP_ABGR :          case XVID_CSP_I420:
407                  safe_packed_conv(                  yuv_to_yv12(image->y, image->u, image->v, src, width, height,
408                          src, src_stride, image->y, image->u, image->v,                                          edged_width);
409                          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;  
410    
411          case XVID_CSP_RGBA :          case XVID_CSP_YV12:             /* u/v swapped */
412                  safe_packed_conv(                  yuv_to_yv12(image->y, image->v, image->u, src, width, height,
413                          src, src_stride, image->y, image->u, image->v,                                          edged_width);
414                          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;  
415    
416          case XVID_CSP_YUY2:          case XVID_CSP_YUY2:
417                  safe_packed_conv(                  yuyv_to_yv12(image->y, image->u, image->v, src, width, height,
418                          src, src_stride, image->y, image->u, image->v,                                           edged_width);
419                          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;  
420    
421          case XVID_CSP_YVYU:             /* u/v swapped */          case XVID_CSP_YVYU:             /* u/v swapped */
422                  safe_packed_conv(                  yuyv_to_yv12(image->y, image->v, image->u, src, width, height,
423                          src, src_stride, image->y, image->v, image->y,                                           edged_width);
424                          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;  
425    
426          case XVID_CSP_UYVY:          case XVID_CSP_UYVY:
427                  safe_packed_conv(                  uyvy_to_yv12(image->y, image->u, image->v, src, width, height,
428                          src, src_stride, image->y, image->u, image->v,                                           edged_width);
429                          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;  
430    
431          case XVID_CSP_USER:          case XVID_CSP_USER:
432                  {                  user_to_yuv_c(image->y, image->u, image->v, edged_width,
433                          DEC_PICTURE * pic = (DEC_PICTURE*)src;                                            (DEC_PICTURE *) src, width, height);
434                          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;  
435    
436          case XVID_CSP_NULL:          case XVID_CSP_NULL:
437                  break;                  break;
438    
         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);  
439                  }                  }
440    
441                  for (i = 0; i < pad_height/2; i++)          return -1;
                 {  
                         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);  
                 }  
         }  
   
 /*  
         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;  
442  }  }
443    
444    
# Line 761  Line 450 
450                           uint32_t edged_width,                           uint32_t edged_width,
451                           uint8_t * dst,                           uint8_t * dst,
452                           uint32_t dst_stride,                           uint32_t dst_stride,
453                           int csp,                           int csp)
                          int interlacing)  
454  {  {
455          const int edged_width2 = edged_width/2;          if (csp & XVID_CSP_VFLIP) {
456          int height2 = height/2;                  height = -height;
   
 /*  
         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)  
         {  
                 dst_stride *= 3;  
         }  
         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;  
457          }          }
         */  
         // ^--- xvid 2.1 compatiblity fix ---^  
   
458    
459          switch (csp & ~XVID_CSP_VFLIP) {          switch (csp & ~XVID_CSP_VFLIP) {
460          case XVID_CSP_RGB555:          case XVID_CSP_RGB555:
461                  safe_packed_conv(                  yv12_to_rgb555(dst, dst_stride, image->y, image->u, image->v,
462                          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);  
463                  return 0;                  return 0;
464    
465          case XVID_CSP_RGB565:          case XVID_CSP_RGB565:
466                  safe_packed_conv(                  yv12_to_rgb565(dst, dst_stride, image->y, image->u, image->v,
467                          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);  
468                  return 0;                  return 0;
469    
470          case XVID_CSP_RGB24:          case XVID_CSP_RGB24:
471                  safe_packed_conv(                  yv12_to_rgb24(dst, dst_stride, image->y, image->u, image->v,
472                          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);  
473                  return 0;                  return 0;
474    
475          case XVID_CSP_RGB32:          case XVID_CSP_RGB32:
476                  safe_packed_conv(                  yv12_to_rgb32(dst, dst_stride, image->y, image->u, image->v,
477                          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);  
478                  return 0;                  return 0;
479    
480          case XVID_CSP_YUY2:          case XVID_CSP_I420:
481                  safe_packed_conv(                  yv12_to_yuv(dst, dst_stride, image->y, image->u, image->v, edged_width,
482                          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);  
483                  return 0;                  return 0;
484    
485          case XVID_CSP_YVYU:             // u,v swapped          case XVID_CSP_YV12:             // u,v swapped
486                  safe_packed_conv(                  yv12_to_yuv(dst, dst_stride, image->y, image->v, image->u, edged_width,
487                          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);  
488                  return 0;                  return 0;
489    
490          case XVID_CSP_UYVY:          case XVID_CSP_YUY2:
491                  safe_packed_conv(                  yv12_to_yuyv(dst, dst_stride, image->y, image->u, image->v,
492                          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);  
493                  return 0;                  return 0;
494    
495          case XVID_CSP_I420:          case XVID_CSP_YVYU:             // u,v swapped
496                  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,
497                          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));  
498                  return 0;                  return 0;
499    
500          case XVID_CSP_YV12:             // u,v swapped          case XVID_CSP_UYVY:
501                  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,
502                          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));  
503                  return 0;                  return 0;
504    
505          case XVID_CSP_USER:          case XVID_CSP_USER:
506                  {                  ((DEC_PICTURE *) dst)->y = image->y;
507                          DEC_PICTURE * pic = (DEC_PICTURE*)dst;                  ((DEC_PICTURE *) dst)->u = image->u;
508                          pic->y = image->y;                  ((DEC_PICTURE *) dst)->v = image->v;
509                          pic->u = image->u;                  ((DEC_PICTURE *) dst)->stride_y = edged_width;
510                          pic->v = image->v;                  ((DEC_PICTURE *) dst)->stride_uv = edged_width / 2;
                         pic->stride_y = edged_width;  
                         pic->stride_uv = edged_width / 2;  
                 }  
511                  return 0;                  return 0;
512    
513          case XVID_CSP_NULL:          case XVID_CSP_NULL:
# Line 1097  Line 710 
710      sV += std2;      sV += std2;
711    }    }
712  }  }
   
   
 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.24

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