[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.25, Tue Nov 26 23:44:10 2002 UTC revision 1.26, Sat Feb 15 15:22:18 2003 UTC
# Line 1  Line 1 
1  /*****************************************************************************  /**************************************************************************
2   *   *
3   *  XVID MPEG-4 VIDEO CODEC   *  XVID MPEG-4 VIDEO CODEC
4   *  - image module -   *      image stuff
5   *   *
6   *  Copyright(C) 2002 Peter Ross <pross@xvid.org>   *      This program is an implementation of a part of one or more MPEG-4
7     *      Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
8     *      to use this software module in hardware or software products are
9     *      advised that its use may infringe existing patents or copyrights, and
10     *      any such use would be at such party's own risk.  The original
11     *      developer of this software module and his/her company, and subsequent
12     *      editors and their companies, will have no liability for use of this
13     *      software or modifications or derivatives thereof.
14   *   *
15   *  This file is part of XviD, a free MPEG-4 video encoder/decoder   *      This program is free software; you can redistribute it and/or modify
16   *   *      it under the terms of the GNU General Public License as published by
  *  XviD is free software; you can redistribute it and/or modify it  
  *  under the terms of the GNU General Public License as published by  
17   *  the Free Software Foundation; either version 2 of the License, or   *  the Free Software Foundation; either version 2 of the License, or
18   *  (at your option) any later version.   *  (at your option) any later version.
19   *   *
# Line 19  Line 24 
24   *   *
25   *  You should have received a copy of the GNU General Public License   *  You should have received a copy of the GNU General Public License
26   *  along with this program; if not, write to the Free Software   *  along with this program; if not, write to the Free Software
27   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *  
  *  Under section 8 of the GNU General Public License, the copyright  
  *  holders of XVID explicitly forbid distribution in the following  
  *  countries:  
  *  
  *    - Japan  
  *    - United States of America  
  *  
  *  Linking XviD statically or dynamically with other modules is making a  
  *  combined work based on XviD.  Thus, the terms and conditions of the  
  *  GNU General Public License cover the whole combination.  
28   *   *
29   *  As a special exception, the copyright holders of XviD give you   *************************************************************************/
30   *  permission to link XviD with independent modules that communicate with  
31   *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the  /**************************************************************************
  *  license terms of these independent modules, and to copy and distribute  
  *  the resulting combined work under terms of your choice, provided that  
  *  every copy of the combined work is accompanied by a complete copy of  
  *  the source code of XviD (the version of XviD used to produce the  
  *  combined work), being distributed under the terms of the GNU General  
  *  Public License plus this exception.  An independent module is a module  
  *  which is not derived from or based on XviD.  
32   *   *
33   *  Note that people who make modified versions of XviD are not obligated   *      History:
  *  to grant this special exception for their modified versions; it is  
  *  their choice whether to do so.  The GNU General Public License gives  
  *  permission to release a modified version without this exception; this  
  *  exception also makes it possible to release a modified version which  
  *  carries forward this exception.  
34   *   *
35   * $Id$   *  05.10.2002  support for interpolated images in qpel mode - Isibaar
36     *      01.05.2002      BFRAME image-based u,v interpolation
37     *  22.04.2002  added some B-frame support
38     *      14.04.2002      added image_dump_yuvpgm(), added image_mad()
39     *              XVID_CSP_USER input support
40     *  09.04.2002  PSNR calculations - Isibaar
41     *      06.04.2002      removed interlaced edging from U,V blocks (as per spec)
42     *  26.03.2002  interlacing support (field-based edging in set_edges)
43     *      26.01.2002      rgb555, rgb565
44     *      07.01.2001      commented u,v interpolation (not required for uv-block-based)
45     *  23.12.2001  removed #ifdefs, added function pointers + init_common()
46     *      22.12.2001      cpu #ifdefs
47     *  19.12.2001  image_dump(); useful for debugging
48     *       6.12.2001      inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>
49   *   *
50   ****************************************************************************/   *************************************************************************/
51    
52  #include <stdlib.h>  #include <stdlib.h>
53  #include <string.h>                             /* memcpy, memset */  #include <string.h>                             // memcpy, memset
54  #include <math.h>  #include <math.h>
55    
56  #include "../portab.h"  #include "../portab.h"
57  #include "../xvid.h"                    /* XVID_CSP_XXX's */  #include "../global.h"                  // XVID_CSP_XXX's
58    #include "../xvid.h"                    // XVID_CSP_XXX's
59  #include "image.h"  #include "image.h"
60  #include "colorspace.h"  #include "colorspace.h"
61  #include "interpolate8x8.h"  #include "interpolate8x8.h"
62    #include "reduced.h"
63  #include "../divx4.h"  #include "../divx4.h"
64  #include "../utils/mem_align.h"  #include "../utils/mem_align.h"
65    
66    #include "font.h"               // XXX: remove later
67    
68  #define SAFETY  64  #define SAFETY  64
69  #define EDGE_SIZE2  (EDGE_SIZE/2)  #define EDGE_SIZE2  (EDGE_SIZE/2)
70    
# Line 203  Line 202 
202          }          }
203    
204    
205  /*U */  //U
206          dst = image->u - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);          dst = image->u - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);
207          src = image->u;          src = image->u;
208    
# Line 231  Line 230 
230          }          }
231    
232    
233  /* V */  // V
234          dst = image->v - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);          dst = image->v - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);
235          src = image->v;          src = image->v;
236    
# Line 259  Line 258 
258          }          }
259  }  }
260    
261  /* bframe encoding requires image-based u,v interpolation */  // bframe encoding requires image-based u,v interpolation
262  void  void
263  image_interpolate(const IMAGE * refn,  image_interpolate(const IMAGE * refn,
264                                    IMAGE * refh,                                    IMAGE * refh,
# Line 267  Line 266 
266                                    IMAGE * refhv,                                    IMAGE * refhv,
267                                    uint32_t edged_width,                                    uint32_t edged_width,
268                                    uint32_t edged_height,                                    uint32_t edged_height,
269                                      uint32_t quarterpel,
270                                    uint32_t rounding)                                    uint32_t rounding)
271  {  {
272          const uint32_t offset = EDGE_SIZE * (edged_width + 1);          const uint32_t offset = EDGE_SIZE2 * (edged_width + 1); // we only interpolate half of the edge area
273          const uint32_t stride_add = 7 * edged_width;          const uint32_t stride_add = 7 * edged_width;
274    /*
275    #ifdef BFRAMES
276            const uint32_t edged_width2 = edged_width / 2;
277            const uint32_t edged_height2 = edged_height / 2;
278            const uint32_t offset2 = EDGE_SIZE2 * (edged_width2 + 1);
279            const uint32_t stride_add2 = 7 * edged_width2;
280    #endif
281    */
282          uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr;          uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr;
283          uint32_t x, y;          uint32_t x, y;
284    
# Line 286  Line 293 
293          v_ptr -= offset;          v_ptr -= offset;
294          hv_ptr -= offset;          hv_ptr -= offset;
295    
296          for (y = 0; y < edged_height; y = y + 8) {          if(quarterpel) {
297                  for (x = 0; x < edged_width; x = x + 8) {  
298                    for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) {
299                            for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) {
300                                    interpolate8x8_6tap_lowpass_h(h_ptr, n_ptr, edged_width, rounding);
301                                    interpolate8x8_6tap_lowpass_v(v_ptr, n_ptr, edged_width, rounding);
302    
303                                    n_ptr += 8;
304                                    h_ptr += 8;
305                                    v_ptr += 8;
306                            }
307    
308                            n_ptr += EDGE_SIZE;
309                            h_ptr += EDGE_SIZE;
310                            v_ptr += EDGE_SIZE;
311    
312                            h_ptr += stride_add;
313                            v_ptr += stride_add;
314                            n_ptr += stride_add;
315                    }
316    
317                    h_ptr = refh->y;
318                    h_ptr -= offset;
319    
320                    for (y = 0; y < (edged_height - EDGE_SIZE); y = y + 8) {
321                            for (x = 0; x < (edged_width - EDGE_SIZE); x = x + 8) {
322                                    interpolate8x8_6tap_lowpass_v(hv_ptr, h_ptr, edged_width, rounding);
323                                    hv_ptr += 8;
324                                    h_ptr += 8;
325                            }
326    
327                            hv_ptr += EDGE_SIZE;
328                            h_ptr += EDGE_SIZE;
329    
330                            hv_ptr += stride_add;
331                            h_ptr += stride_add;
332                    }
333            }
334            else {
335    
336                    for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) {
337                            for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) {
338                          interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding);                          interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding);
339                          interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding);                          interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding);
340                          interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding);                          interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding);
# Line 297  Line 344 
344                          v_ptr += 8;                          v_ptr += 8;
345                          hv_ptr += 8;                          hv_ptr += 8;
346                  }                  }
347    
348                            h_ptr += EDGE_SIZE;
349                            v_ptr += EDGE_SIZE;
350                            hv_ptr += EDGE_SIZE;
351                            n_ptr += EDGE_SIZE;
352    
353                  h_ptr += stride_add;                  h_ptr += stride_add;
354                  v_ptr += stride_add;                  v_ptr += stride_add;
355                  hv_ptr += stride_add;                  hv_ptr += stride_add;
356                  n_ptr += stride_add;                  n_ptr += stride_add;
357          }          }
358            }
359    /*
360    #ifdef BFRAMES
361            n_ptr = refn->u;
362            h_ptr = refh->u;
363            v_ptr = refv->u;
364            hv_ptr = refhv->u;
365    
366            n_ptr -= offset2;
367            h_ptr -= offset2;
368            v_ptr -= offset2;
369            hv_ptr -= offset2;
370    
371            for (y = 0; y < edged_height2; y += 8) {
372                    for (x = 0; x < edged_width2; x += 8) {
373                            interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);
374                            interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);
375                            interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);
376    
377                            n_ptr += 8;
378                            h_ptr += 8;
379                            v_ptr += 8;
380                            hv_ptr += 8;
381                    }
382                    h_ptr += stride_add2;
383                    v_ptr += stride_add2;
384                    hv_ptr += stride_add2;
385                    n_ptr += stride_add2;
386            }
387    
388            n_ptr = refn->v;
389            h_ptr = refh->v;
390            v_ptr = refv->v;
391            hv_ptr = refhv->v;
392    
393            n_ptr -= offset2;
394            h_ptr -= offset2;
395            v_ptr -= offset2;
396            hv_ptr -= offset2;
397    
398            for (y = 0; y < edged_height2; y = y + 8) {
399                    for (x = 0; x < edged_width2; x = x + 8) {
400                            interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);
401                            interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);
402                            interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);
403    
404                            n_ptr += 8;
405                            h_ptr += 8;
406                            v_ptr += 8;
407                            hv_ptr += 8;
408                    }
409                    h_ptr += stride_add2;
410                    v_ptr += stride_add2;
411                    hv_ptr += stride_add2;
412                    n_ptr += stride_add2;
413            }
414    #endif
415    */
416          /*          /*
417             interpolate_halfpel_h(             interpolate_halfpel_h(
418             refh->y - offset,             refh->y - offset,
# Line 366  Line 476 
476  }  }
477    
478    
479    /*
480    chroma optimize filter, invented by mf
481    a chroma pixel is average from the surrounding pixels, when the
482    correpsonding luma pixels are pure black or white.
483    */
484    
485    void
486    image_chroma_optimize(IMAGE * img, int width, int height, int edged_width)
487    {
488            int x,y;
489            int pixels = 0;
490    
491            for (y = 1; y < height/2 - 1; y++)
492            for (x = 1; x < width/2 - 1; x++)
493            {
494    #define IS_PURE(a)  ((a)<=16||(a)>=235)
495    #define IMG_Y(Y,X)      img->y[(Y)*edged_width + (X)]
496    #define IMG_U(Y,X)      img->u[(Y)*edged_width/2 + (X)]
497    #define IMG_V(Y,X)      img->v[(Y)*edged_width/2 + (X)]
498    
499                    if (IS_PURE(IMG_Y(y*2  ,x*2  )) &&
500                            IS_PURE(IMG_Y(y*2  ,x*2+1)) &&
501                            IS_PURE(IMG_Y(y*2+1,x*2  )) &&
502                            IS_PURE(IMG_Y(y*2+1,x*2+1)))
503                    {
504                            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;
505                            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;
506                            pixels++;
507                    }
508    
509    #undef IS_PURE
510    #undef IMG_Y
511    #undef IMG_U
512    #undef IMG_V
513            }
514    
515            DPRINTF(DPRINTF_DEBUG,"chroma_optimized_pixels = %i/%i", pixels, width*height/4);
516    }
517    
518    
519    
520    
521    
522    /*
523      perform safe packed colorspace conversion, by splitting
524      the image up into an optimized area (pixel width divisible by 16),
525      and two unoptimized/plain-c areas (pixel width divisible by 2)
526    */
527    
528    static void
529    safe_packed_conv(uint8_t * x_ptr, int x_stride,
530                                     uint8_t * y_ptr, uint8_t * u_ptr, uint8_t * v_ptr,
531                                     int y_stride, int uv_stride,
532                                     int width, int height, int vflip,
533                                     packedFunc * func_opt, packedFunc func_c, int size)
534    {
535            int width_opt, width_c;
536    
537            if (func_opt != func_c && x_stride < size*((width+15)/16)*16)
538            {
539                    width_opt = width & (~15);
540                    width_c = width - width_opt;
541            }
542            else
543            {
544                    width_opt = width;
545                    width_c = 0;
546            }
547    
548            func_opt(x_ptr, x_stride,
549                            y_ptr, u_ptr, v_ptr, y_stride, uv_stride,
550                            width_opt, height, vflip);
551    
552            if (width_c)
553            {
554                    func_c(x_ptr + size*width_opt, x_stride,
555                            y_ptr + width_opt, u_ptr + width_opt/2, v_ptr + width_opt/2,
556                            y_stride, uv_stride, width_c, height, vflip);
557            }
558    }
559    
560    
561    
562  int  int
563  image_input(IMAGE * image,  image_input(IMAGE * image,
564                          uint32_t width,                          uint32_t width,
565                          int height,                          int height,
566                          uint32_t edged_width,                          uint32_t edged_width,
567                          uint8_t * src,                          uint8_t * src,
568                          int csp)                          int src_stride,
569                            int csp,
570                            int interlacing)
571  {  {
572            const int edged_width2 = edged_width/2;
573            const int width2 = width/2;
574            const int height2 = height/2;
575            //const int height_signed = (csp & XVID_CSP_VFLIP) ? -height : height;
576    
577    
578  /*      if (csp & XVID_CSP_VFLIP)          //      int src_stride = width;
579    
580            // --- xvid 2.1 compatiblity patch ---
581            // --- remove when xvid_dec_frame->stride equals real stride
582            /*
583            if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB555 ||
584                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB565 ||
585                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YUY2 ||
586                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YVYU ||
587                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_UYVY)
588            {
589                    src_stride *= 2;
590            }
591            else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24)
592            {
593                    src_stride *= 3;
594            }
595            else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 ||
596                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR ||
597                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA)
598          {          {
599                  height = -height;                  src_stride *= 4;
600          }          }
601  */  */
602            // ^--- xvid 2.1 compatiblity fix ---^
603    
604          switch (csp & ~XVID_CSP_VFLIP) {          switch (csp & ~XVID_CSP_VFLIP) {
605          case XVID_CSP_RGB555:          case XVID_CSP_RGB555:
606                  rgb555_to_yv12(image->y, image->u, image->v, src, width, height,                  safe_packed_conv(
607                                             edged_width);                          src, src_stride, image->y, image->u, image->v,
608                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
609                            interlacing?rgb555i_to_yv12  :rgb555_to_yv12,
610                            interlacing?rgb555i_to_yv12_c:rgb555_to_yv12_c, 2);
611                    break;
612    
613          case XVID_CSP_RGB565:          case XVID_CSP_RGB565:
614                  rgb565_to_yv12(image->y, image->u, image->v, src, width, height,                  safe_packed_conv(
615                                             edged_width);                          src, src_stride, image->y, image->u, image->v,
616                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
617                            interlacing?rgb565i_to_yv12  :rgb565_to_yv12,
618                            interlacing?rgb565i_to_yv12_c:rgb565_to_yv12_c, 2);
619                    break;
620    
621    
622          case XVID_CSP_RGB24:          case XVID_CSP_RGB24:
623                  rgb24_to_yv12(image->y, image->u, image->v, src, width, height,                  safe_packed_conv(
624                                            edged_width);                          src, src_stride, image->y, image->u, image->v,
625                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
626                            interlacing?bgri_to_yv12  :bgr_to_yv12,
627                            interlacing?bgri_to_yv12_c:bgr_to_yv12_c, 3);
628                    break;
629    
630          case XVID_CSP_RGB32:          case XVID_CSP_RGB32:
631                  rgb32_to_yv12(image->y, image->u, image->v, src, width, height,                  safe_packed_conv(
632                                            edged_width);                          src, src_stride, image->y, image->u, image->v,
633                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
634                            interlacing?bgrai_to_yv12  :bgra_to_yv12,
635                            interlacing?bgrai_to_yv12_c:bgra_to_yv12_c, 4);
636                    break;
637    
638          case XVID_CSP_I420:          case XVID_CSP_ABGR :
639                  yuv_to_yv12(image->y, image->u, image->v, src, width, height,                  safe_packed_conv(
640                                          edged_width);                          src, src_stride, image->y, image->u, image->v,
641                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
642                            interlacing?abgri_to_yv12  :abgr_to_yv12,
643                            interlacing?abgri_to_yv12_c:abgr_to_yv12_c, 4);
644                    break;
645    
646          case XVID_CSP_YV12:             /* u/v swapped */          case XVID_CSP_RGBA :
647                  yuv_to_yv12(image->y, image->v, image->u, src, width, height,                  safe_packed_conv(
648                                          edged_width);                          src, src_stride, image->y, image->u, image->v,
649                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
650                            interlacing?rgbai_to_yv12  :rgba_to_yv12,
651                            interlacing?rgbai_to_yv12_c:rgba_to_yv12_c, 4);
652                    break;
653    
654          case XVID_CSP_YUY2:          case XVID_CSP_YUY2:
655                  yuyv_to_yv12(image->y, image->u, image->v, src, width, height,                  safe_packed_conv(
656                                           edged_width);                          src, src_stride, image->y, image->u, image->v,
657                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
658                            interlacing?yuyvi_to_yv12  :yuyv_to_yv12,
659                            interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2);
660                    break;
661    
662          case XVID_CSP_YVYU:             /* u/v swapped */          case XVID_CSP_YVYU:             /* u/v swapped */
663                  yuyv_to_yv12(image->y, image->v, image->u, src, width, height,                  safe_packed_conv(
664                                           edged_width);                          src, src_stride, image->y, image->v, image->y,
665                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
666                            interlacing?yuyvi_to_yv12  :yuyv_to_yv12,
667                            interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2);
668                    break;
669    
670          case XVID_CSP_UYVY:          case XVID_CSP_UYVY:
671                  uyvy_to_yv12(image->y, image->u, image->v, src, width, height,                  safe_packed_conv(
672                                           edged_width);                          src, src_stride, image->y, image->u, image->v,
673                  return 0;                          edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
674                            interlacing?uyvyi_to_yv12  :uyvy_to_yv12,
675                            interlacing?uyvyi_to_yv12_c:uyvy_to_yv12_c, 2);
676                    break;
677    
678            case XVID_CSP_I420:
679                    yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2,
680                            src, src + src_stride*height, src + src_stride*height + (src_stride/2)*height2,
681                            src_stride, src_stride/2, width, height, (csp & XVID_CSP_VFLIP));
682                    break
683                            ;
684            case XVID_CSP_YV12:             /* u/v swapped */
685                    yv12_to_yv12(image->y, image->v, image->u, edged_width, edged_width2,
686                            src, src + src_stride*height, src + src_stride*height + (src_stride/2)*height2,
687                            src_stride, src_stride/2, width, height, (csp & XVID_CSP_VFLIP));
688                    break;
689    
690          case XVID_CSP_USER:          case XVID_CSP_USER:
691                  user_to_yuv_c(image->y, image->u, image->v, edged_width,                  {
692                                            (DEC_PICTURE *) src, width, height);                          DEC_PICTURE * pic = (DEC_PICTURE*)src;
693                  return 0;                          yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2,
694                                    pic->y, pic->u, pic->v, pic->stride_y, pic->stride_y,
695                                    width, height, (csp & XVID_CSP_VFLIP));
696                    }
697                    break;
698    
699          case XVID_CSP_NULL:          case XVID_CSP_NULL:
700                  break;                  break;
701    
702            default :
703                    return -1;
704          }          }
705    
706          return -1;  
707            /* pad out image when the width and/or height is not a multiple of 16 */
708    
709            if (width & 15)
710            {
711                    int i;
712                    int pad_width = 16 - (width&15);
713                    for (i = 0; i < height; i++)
714                    {
715                            memset(image->y + i*edged_width + width,
716                                     *(image->y + i*edged_width + width - 1), pad_width);
717                    }
718                    for (i = 0; i < height/2; i++)
719                    {
720                            memset(image->u + i*edged_width2 + width2,
721                                     *(image->u + i*edged_width2 + width2 - 1),pad_width/2);
722                            memset(image->v + i*edged_width2 + width2,
723                                     *(image->v + i*edged_width2 + width2 - 1),pad_width/2);
724                    }
725            }
726    
727            if (height & 15)
728            {
729                    int pad_height = 16 - (height&15);
730                    int length = ((width+15)/16)*16;
731                    int i;
732                    for (i = 0; i < pad_height; i++)
733                    {
734                            memcpy(image->y + (height+i)*edged_width,
735                                       image->y + (height-1)*edged_width,length);
736                    }
737    
738                    for (i = 0; i < pad_height/2; i++)
739                    {
740                            memcpy(image->u + (height2+i)*edged_width2,
741                                       image->u + (height2-1)*edged_width2,length/2);
742                            memcpy(image->v + (height2+i)*edged_width2,
743                                       image->v + (height2-1)*edged_width2,length/2);
744                    }
745            }
746    
747    /*
748            if (interlacing)
749                    image_printf(image, edged_width, height, 5,5, "[i]");
750            image_dump_yuvpgm(image, edged_width, ((width+15)/16)*16, ((height+15)/16)*16, "\\encode.pgm");
751    */
752            return 0;
753  }  }
754    
755    
# Line 450  Line 761 
761                           uint32_t edged_width,                           uint32_t edged_width,
762                           uint8_t * dst,                           uint8_t * dst,
763                           uint32_t dst_stride,                           uint32_t dst_stride,
764                           int csp)                           int csp,
765                             int interlacing)
766    {
767            const int edged_width2 = edged_width/2;
768            int height2 = height/2;
769    
770    /*
771            if (interlacing)
772                    image_printf(image, edged_width, height, 5,100, "[i]=%i,%i",width,height);
773            image_dump_yuvpgm(image, edged_width, width, height, "\\decode.pgm");
774    */
775    
776    
777            // --- xvid 2.1 compatiblity patch ---
778            // --- remove when xvid_dec_frame->stride equals real stride
779            /*
780            if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB555 ||
781                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB565 ||
782                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YUY2 ||
783                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YVYU ||
784                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_UYVY)
785            {
786                    dst_stride *= 2;
787            }
788            else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24)
789  {  {
790          if (csp & XVID_CSP_VFLIP) {                  dst_stride *= 3;
                 height = -height;  
791          }          }
792            else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 ||
793                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR ||
794                    (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA)
795            {
796                    dst_stride *= 4;
797            }
798            */
799            // ^--- xvid 2.1 compatiblity fix ---^
800    
801    
802          switch (csp & ~XVID_CSP_VFLIP) {          switch (csp & ~XVID_CSP_VFLIP) {
803          case XVID_CSP_RGB555:          case XVID_CSP_RGB555:
804                  yv12_to_rgb555(dst, dst_stride, image->y, image->u, image->v,                  safe_packed_conv(
805                                             edged_width, edged_width / 2, width, height);                          dst, dst_stride, image->y, image->u, image->v,
806                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
807                            interlacing?yv12_to_rgb555i  :yv12_to_rgb555,
808                            interlacing?yv12_to_rgb555i_c:yv12_to_rgb555_c, 2);
809                  return 0;                  return 0;
810    
811          case XVID_CSP_RGB565:          case XVID_CSP_RGB565:
812                  yv12_to_rgb565(dst, dst_stride, image->y, image->u, image->v,                  safe_packed_conv(
813                                             edged_width, edged_width / 2, width, height);                          dst, dst_stride, image->y, image->u, image->v,
814                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
815                            interlacing?yv12_to_rgb565i  :yv12_to_rgb565,
816                            interlacing?yv12_to_rgb565i_c:yv12_to_rgb565_c, 2);
817                  return 0;                  return 0;
818    
819          case XVID_CSP_RGB24:          case XVID_CSP_RGB24:
820                  yv12_to_rgb24(dst, dst_stride, image->y, image->u, image->v,                  safe_packed_conv(
821                                            edged_width, edged_width / 2, width, height);                          dst, dst_stride, image->y, image->u, image->v,
822                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
823                            interlacing?yv12_to_bgri  :yv12_to_bgr,
824                            interlacing?yv12_to_bgri_c:yv12_to_bgr_c, 3);
825                  return 0;                  return 0;
826    
827          case XVID_CSP_RGB32:          case XVID_CSP_RGB32:
828                  yv12_to_rgb32(dst, dst_stride, image->y, image->u, image->v,                  safe_packed_conv(
829                                            edged_width, edged_width / 2, width, height);                          dst, dst_stride, image->y, image->u, image->v,
830                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
831                            interlacing?yv12_to_bgrai  :yv12_to_bgra,
832                            interlacing?yv12_to_bgrai_c:yv12_to_bgra_c, 4);
833                    return 0;
834    
835            case XVID_CSP_ABGR:
836                    safe_packed_conv(
837                            dst, dst_stride, image->y, image->u, image->v,
838                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
839                            interlacing?yv12_to_abgri  :yv12_to_abgr,
840                            interlacing?yv12_to_abgri_c:yv12_to_abgr_c, 4);
841                    return 0;
842    
843            case XVID_CSP_RGBA:
844                    safe_packed_conv(
845                            dst, dst_stride, image->y, image->u, image->v,
846                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
847                            interlacing?yv12_to_rgbai  :yv12_to_rgba,
848                            interlacing?yv12_to_rgbai_c:yv12_to_rgba_c, 4);
849                  return 0;                  return 0;
850    
851          case XVID_CSP_I420:          case XVID_CSP_YUY2:
852                  yv12_to_yuv(dst, dst_stride, image->y, image->u, image->v, edged_width,                  safe_packed_conv(
853                                          edged_width / 2, width, height);                          dst, dst_stride, image->y, image->u, image->v,
854                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
855                            interlacing?yv12_to_yuyvi  :yv12_to_yuyv,
856                            interlacing?yv12_to_yuyvi_c:yv12_to_yuyv_c, 2);
857                  return 0;                  return 0;
858    
859          case XVID_CSP_YV12:             /* u,v swapped */          case XVID_CSP_YVYU:             // u,v swapped
860                  yv12_to_yuv(dst, dst_stride, image->y, image->v, image->u, edged_width,                  safe_packed_conv(
861                                          edged_width / 2, width, height);                          dst, dst_stride, image->y, image->v, image->u,
862                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
863                            interlacing?yv12_to_yuyvi  :yv12_to_yuyv,
864                            interlacing?yv12_to_yuyvi_c:yv12_to_yuyv_c, 2);
865                  return 0;                  return 0;
866    
867          case XVID_CSP_YUY2:          case XVID_CSP_UYVY:
868                  yv12_to_yuyv(dst, dst_stride, image->y, image->u, image->v,                  safe_packed_conv(
869                                           edged_width, edged_width / 2, width, height);                          dst, dst_stride, image->y, image->u, image->v,
870                            edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
871                            interlacing?yv12_to_uyvyi  :yv12_to_uyvy,
872                            interlacing?yv12_to_uyvyi_c:yv12_to_uyvy_c, 2);
873                  return 0;                  return 0;
874    
875          case XVID_CSP_YVYU:             /* u,v swapped */          case XVID_CSP_I420:
876                  yv12_to_yuyv(dst, dst_stride, image->y, image->v, image->u,                  yv12_to_yv12(dst, dst + dst_stride*height, dst + dst_stride*height + (dst_stride/2)*height2,
877                                           edged_width, edged_width / 2, width, height);                          dst_stride, dst_stride/2,
878                            image->y, image->u, image->v, edged_width, edged_width2,
879                            width, height, (csp & XVID_CSP_VFLIP));
880                  return 0;                  return 0;
881    
882          case XVID_CSP_UYVY:          case XVID_CSP_YV12:             // u,v swapped
883                  yv12_to_uyvy(dst, dst_stride, image->y, image->u, image->v,                  yv12_to_yv12(dst, dst + dst_stride*height, dst + dst_stride*height + (dst_stride/2)*height2,
884                                           edged_width, edged_width / 2, width, height);                          dst_stride, dst_stride/2,
885                            image->y, image->v, image->u, edged_width, edged_width2,
886                            width, height, (csp & XVID_CSP_VFLIP));
887                  return 0;                  return 0;
888    
889          case XVID_CSP_USER:          case XVID_CSP_USER:
890                  ((DEC_PICTURE *) dst)->y = image->y;                  {
891                  ((DEC_PICTURE *) dst)->u = image->u;                          DEC_PICTURE * pic = (DEC_PICTURE*)dst;
892                  ((DEC_PICTURE *) dst)->v = image->v;                          pic->y = image->y;
893                  ((DEC_PICTURE *) dst)->stride_y = edged_width;                          pic->u = image->u;
894                  ((DEC_PICTURE *) dst)->stride_uv = edged_width / 2;                          pic->v = image->v;
895                            pic->stride_y = edged_width;
896                            pic->stride_uv = edged_width / 2;
897                    }
898                  return 0;                  return 0;
899    
900          case XVID_CSP_NULL:          case XVID_CSP_NULL:
# Line 551  Line 938 
938          return psnr_y;          return psnr_y;
939  }  }
940    
941  #if     0  
942    float sse_to_PSNR(long sse, int pixels)
943    {
944            if (sse==0)
945                    return 99.99F;
946    
947            return 48.131F - 10*(float)log10((float)sse/(float)(pixels));   // log10(255*255)=4.8131
948    
949    }
950    
951    long plane_sse(uint8_t * orig,
952                       uint8_t * recon,
953                       uint16_t stride,
954                       uint16_t width,
955                       uint16_t height)
956    {
957            int diff, x, y;
958            long sse=0;
959    
960            for (y = 0; y < height; y++) {
961                    for (x = 0; x < width; x++) {
962                            diff = *(orig + x) - *(recon + x);
963                            sse += diff * diff;
964                    }
965                    orig += stride;
966                    recon += stride;
967            }
968            return sse;
969    }
970    
971    /*
972    
973  #include <stdio.h>  #include <stdio.h>
974  #include <string.h>  #include <string.h>
# Line 575  Line 992 
992  }  }
993    
994    
995  /* dump image+edges to yuv pgm files  */  // dump image+edges to yuv pgm files
996    
997  int image_dump(IMAGE * image, uint32_t edged_width, uint32_t edged_height, char * path, int number)  int image_dump(IMAGE * image, uint32_t edged_width, uint32_t edged_height, char * path, int number)
998  {  {
# Line 598  Line 1015 
1015    
1016          return 0;          return 0;
1017  }  }
1018  #endif  */
1019    
1020    
1021    
# Line 647  Line 1064 
1064  }  }
1065    
1066    
 #define ABS(X)    (((X)>0)?(X):-(X))  
1067  float  float
1068  image_mad(const IMAGE * img1,  image_mad(const IMAGE * img1,
1069                    const IMAGE * img2,                    const IMAGE * img2,
# Line 710  Line 1126 
1126      sV += std2;      sV += std2;
1127    }    }
1128  }  }
1129    
1130    
1131    void
1132    image_clear(IMAGE * img, int width, int height, int edged_width,
1133                                            int y, int u, int v)
1134    {
1135            uint8_t * p;
1136            int i;
1137    
1138            p = img->y;
1139            for (i = 0; i < height; i++) {
1140                    memset(p, y, width);
1141                    p += edged_width;
1142            }
1143    
1144            p = img->u;
1145            for (i = 0; i < height/2; i++) {
1146                    memset(p, u, width/2);
1147                    p += edged_width/2;
1148            }
1149    
1150            p = img->v;
1151            for (i = 0; i < height/2; i++) {
1152                    memset(p, v, width/2);
1153                    p += edged_width/2;
1154            }
1155    }
1156    
1157    
1158    /* reduced resolution deblocking filter
1159            block = block size (16=rrv, 8=full resolution)
1160            flags = XVID_DEC_YDEBLOCK|XVID_DEC_UVDEBLOCK
1161    */
1162    void
1163    image_deblock_rrv(IMAGE * img, int edged_width,
1164                                    const MACROBLOCK * mbs, int mb_width, int mb_height, int mb_stride,
1165                                    int block, int flags)
1166    {
1167            const int edged_width2 = edged_width /2;
1168            const int nblocks = block / 8;  /* skals code uses 8pixel block uints */
1169            int i,j;
1170    
1171            /* luma: j,i in block units */
1172            if ((flags & XVID_DEC_DEBLOCKY))
1173            {
1174                    for (j = 1; j < mb_height*2; j++)               /* horizontal deblocking */
1175                    for (i = 0; i < mb_width*2; i++)
1176                    {
1177                            if (mbs[(j-1)/2*mb_stride + (i/2)].mode != MODE_NOT_CODED ||
1178                                    mbs[(j+0)/2*mb_stride + (i/2)].mode != MODE_NOT_CODED)
1179                            {
1180                                    hfilter_31(img->y + (j*block - 1)*edged_width + i*block,
1181                                                                      img->y + (j*block + 0)*edged_width + i*block, nblocks);
1182                            }
1183                    }
1184    
1185                    for (j = 0; j < mb_height*2; j++)               /* vertical deblocking */
1186                    for (i = 1; i < mb_width*2; i++)
1187                    {
1188                            if (mbs[(j/2)*mb_stride + (i-1)/2].mode != MODE_NOT_CODED ||
1189                                    mbs[(j/2)*mb_stride + (i+0)/2].mode != MODE_NOT_CODED)
1190                            {
1191                                    vfilter_31(img->y + (j*block)*edged_width + i*block - 1,
1192                                                       img->y + (j*block)*edged_width + i*block + 0,
1193                                                       edged_width, nblocks);
1194                            }
1195                    }
1196            }
1197    
1198    
1199            /* chroma */
1200            if ((flags & XVID_DEC_DEBLOCKUV))
1201            {
1202                    for (j = 1; j < mb_height; j++)         /* horizontal deblocking */
1203                    for (i = 0; i < mb_width; i++)
1204                    {
1205                            if (mbs[(j-1)*mb_stride + i].mode != MODE_NOT_CODED ||
1206                                    mbs[(j+0)*mb_stride + i].mode != MODE_NOT_CODED)
1207                            {
1208                                    hfilter_31(img->u + (j*block - 1)*edged_width2 + i*block,
1209                                                       img->u + (j*block + 0)*edged_width2 + i*block, nblocks);
1210                                    hfilter_31(img->v + (j*block - 1)*edged_width2 + i*block,
1211                                                       img->v + (j*block + 0)*edged_width2 + i*block, nblocks);
1212                            }
1213                    }
1214    
1215                    for (j = 0; j < mb_height; j++)         /* vertical deblocking */
1216                    for (i = 1; i < mb_width; i++)
1217                    {
1218                            if (mbs[j*mb_stride + i - 1].mode != MODE_NOT_CODED ||
1219                                    mbs[j*mb_stride + i + 0].mode != MODE_NOT_CODED)
1220                            {
1221                                    vfilter_31(img->u + (j*block)*edged_width2 + i*block - 1,
1222                                                       img->u + (j*block)*edged_width2 + i*block + 0,
1223                                                       edged_width2, nblocks);
1224                                    vfilter_31(img->v + (j*block)*edged_width2 + i*block - 1,
1225                                                       img->v + (j*block)*edged_width2 + i*block + 0,
1226                                                       edged_width2, nblocks);
1227                            }
1228                    }
1229            }
1230    
1231    }
1232    

Legend:
Removed from v.1.25  
changed lines
  Added in v.1.26

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