[xiph-cvs] cvs commit: theora/lib block_inline.h blockmap.c dct.c dct_decode.c decode.c frinit.c pb.c pp.h quant.c quant_lookup.h reconstruct.c scan.c toplevel_lookup.h dct_encode.c encode.c encoder_internal.h encoder_lookup.h frarray.c huffman.c idct.c mcomp.c misc_common.c pp.c toplevel.c

Monty xiphmont at xiph.org
Fri Sep 20 02:30:34 PDT 2002



xiphmont    02/09/20 05:30:33

  Modified:    lib      dct_encode.c encode.c encoder_internal.h
                        encoder_lookup.h frarray.c huffman.c idct.c mcomp.c
                        misc_common.c pp.c toplevel.c
  Added:       lib      block_inline.h blockmap.c dct.c dct_decode.c
                        decode.c frinit.c pb.c pp.h quant.c quant_lookup.h
                        reconstruct.c scan.c toplevel_lookup.h
  Log:
  Incremental; avoid losing work

Revision  Changes    Path
1.3       +98 -110   theora/lib/dct_encode.c

Index: dct_encode.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/dct_encode.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- dct_encode.c	18 Sep 2002 08:56:56 -0000	1.2
+++ dct_encode.c	20 Sep 2002 09:30:32 -0000	1.3
@@ -11,15 +11,15 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: dct_encode.c,v 1.2 2002/09/18 08:56:56 xiphmont Exp $
+  last mod: $Id: dct_encode.c,v 1.3 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
 #include "encoder_internal.h"
 
-int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
+static int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
 
-void SUB8 (unsigned char *FiltPtr, unsigned char *ReconPtr, 
+void Sub8 (unsigned char *FiltPtr, unsigned char *ReconPtr, 
            ogg_int16_t *DctInputPtr, unsigned char *old_ptr1, 
            unsigned char *new_ptr1, ogg_uint32_t PixelsPerLine, 
            ogg_uint32_t ReconPixelsPerLine ) {
@@ -49,7 +49,7 @@
   }
 }
 
-void SUB8_128 (unsigned char *FiltPtr, ogg_int16_t *DctInputPtr, 
+void Sub8_128 (unsigned char *FiltPtr, ogg_int16_t *DctInputPtr, 
                unsigned char *old_ptr1, unsigned char *new_ptr1, 
                ogg_uint32_t PixelsPerLine ) {
   int i;
@@ -80,7 +80,7 @@
   }
 }
 
-void SUB8AV2 (unsigned char *FiltPtr, unsigned char *ReconPtr1, 
+void Sub8Av2 (unsigned char *FiltPtr, unsigned char *ReconPtr1, 
               unsigned char *ReconPtr2, ogg_int16_t *DctInputPtr, 
               unsigned char *old_ptr1, unsigned char *new_ptr1, 
               ogg_uint32_t PixelsPerLine, ogg_uint32_t ReconPixelsPerLine ) {
@@ -126,90 +126,87 @@
   
   /* Values are tokenised as category value and a number of additional
      bits that define the position within the category.  */
-
-    if ( DataValue == 0 ) {
-      IssueWarning( "Bad Input to TokenizeDctValue" );
-    } else if ( AbsDataVal == 1 ){
-      if ( DataValue == 1 )
-	TokenListPtr[0] = ONE_TOKEN; 
-      else
-	TokenListPtr[0] = MINUS_ONE_TOKEN; 
-      tokens_added = 1;
-    } else if ( AbsDataVal == 2 ) {
-      if ( DataValue == 2 )
-	TokenListPtr[0] = TWO_TOKEN; 
-      else
-	TokenListPtr[0] = MINUS_TWO_TOKEN; 
-      tokens_added = 1;
-    } else if ( AbsDataVal <= MAX_SINGLE_TOKEN_VALUE ) {   
-      TokenListPtr[0] = LOW_VAL_TOKENS + (AbsDataVal - DCT_VAL_CAT2_MIN); 
-      if ( DataValue > 0 )
-	TokenListPtr[1] = 0;
-      else
-	TokenListPtr[1] = 1;
-      tokens_added = 2;
-    } else if ( AbsDataVal <= 8 ) {
-      /* Bit 1 determines sign, Bit 0 the value */
-      TokenListPtr[0] = DCT_VAL_CATEGORY3; 
-      if ( DataValue > 0 )
-	TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT3_MIN);
-      else
-	TokenListPtr[1] = (0x02) + (AbsDataVal - DCT_VAL_CAT3_MIN);
-      tokens_added = 2;
-    } else if ( AbsDataVal <= 12 ) {
-      /* Bit 2 determines sign, Bit 0-2 the value */
-      TokenListPtr[0] = DCT_VAL_CATEGORY4; 
-      if ( DataValue > 0 )
-	TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT4_MIN);
-      else
-	TokenListPtr[1] = (0x04) + (AbsDataVal - DCT_VAL_CAT4_MIN);
-      tokens_added = 2;
-    } else if ( AbsDataVal <= 20 ) {
-      /* Bit 3 determines sign, Bit 0-2 the value */
-      TokenListPtr[0] = DCT_VAL_CATEGORY5;    
-      if ( DataValue > 0 )
-	TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT5_MIN);
-      else
-	TokenListPtr[1] = (0x08) + (AbsDataVal - DCT_VAL_CAT5_MIN);
-      tokens_added = 2;
-    } else if ( AbsDataVal <= 36 ) {
-      /* Bit 4 determines sign, Bit 0-3 the value */
-      TokenListPtr[0] = DCT_VAL_CATEGORY6;    
-      if ( DataValue > 0 )
-	TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT6_MIN);
-      else
-            TokenListPtr[1] = (0x010) + (AbsDataVal - DCT_VAL_CAT6_MIN);
-      tokens_added = 2;
-    } else if ( AbsDataVal <= 68 ) {
-      /* Bit 5 determines sign, Bit 0-4 the value */
-      TokenListPtr[0] = DCT_VAL_CATEGORY7;    
-      if ( DataValue > 0 )
-	TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT7_MIN);
-      else
-	TokenListPtr[1] = (0x20) + (AbsDataVal - DCT_VAL_CAT7_MIN);
-      tokens_added = 2;
-    } else if ( AbsDataVal <= 511 ) {
-      /* Bit 9 determines sign, Bit 0-8 the value */
-      TokenListPtr[0] = DCT_VAL_CATEGORY8;    
-      if ( DataValue > 0 )
-	TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT8_MIN);
-      else
-	TokenListPtr[1] = (0x200) + (AbsDataVal - DCT_VAL_CAT8_MIN);
-      tokens_added = 2;
-    } else {
-      TokenListPtr[0] = DCT_VAL_CATEGORY8;    
-      if ( DataValue > 0 )
-	TokenListPtr[1] = (511 - DCT_VAL_CAT8_MIN);
-      else
-	TokenListPtr[1] = (0x200) + (511 - DCT_VAL_CAT8_MIN);
-      tokens_added = 2;
-      
-      tokens_added = 2;  /* ERROR */
-      IssueWarning( "Bad Input to TokenizeDctValue" );
-    }
-    
-    /* Return the total number of tokens added */
-    return tokens_added;
+  
+  if ( DataValue == 0 ) return 0;
+  
+  if ( AbsDataVal == 1 ){
+    if ( DataValue == 1 )
+      TokenListPtr[0] = ONE_TOKEN; 
+    else
+      TokenListPtr[0] = MINUS_ONE_TOKEN; 
+    tokens_added = 1;
+  } else if ( AbsDataVal == 2 ) {
+    if ( DataValue == 2 )
+      TokenListPtr[0] = TWO_TOKEN; 
+    else
+      TokenListPtr[0] = MINUS_TWO_TOKEN; 
+    tokens_added = 1;
+  } else if ( AbsDataVal <= MAX_SINGLE_TOKEN_VALUE ) {   
+    TokenListPtr[0] = LOW_VAL_TOKENS + (AbsDataVal - DCT_VAL_CAT2_MIN); 
+    if ( DataValue > 0 )
+      TokenListPtr[1] = 0;
+    else
+      TokenListPtr[1] = 1;
+    tokens_added = 2;
+  } else if ( AbsDataVal <= 8 ) {
+    /* Bit 1 determines sign, Bit 0 the value */
+    TokenListPtr[0] = DCT_VAL_CATEGORY3; 
+    if ( DataValue > 0 )
+      TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT3_MIN);
+    else
+      TokenListPtr[1] = (0x02) + (AbsDataVal - DCT_VAL_CAT3_MIN);
+    tokens_added = 2;
+  } else if ( AbsDataVal <= 12 ) {
+    /* Bit 2 determines sign, Bit 0-2 the value */
+    TokenListPtr[0] = DCT_VAL_CATEGORY4; 
+    if ( DataValue > 0 )
+      TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT4_MIN);
+    else
+      TokenListPtr[1] = (0x04) + (AbsDataVal - DCT_VAL_CAT4_MIN);
+    tokens_added = 2;
+  } else if ( AbsDataVal <= 20 ) {
+    /* Bit 3 determines sign, Bit 0-2 the value */
+    TokenListPtr[0] = DCT_VAL_CATEGORY5;    
+    if ( DataValue > 0 )
+      TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT5_MIN);
+    else
+      TokenListPtr[1] = (0x08) + (AbsDataVal - DCT_VAL_CAT5_MIN);
+    tokens_added = 2;
+  } else if ( AbsDataVal <= 36 ) {
+    /* Bit 4 determines sign, Bit 0-3 the value */
+    TokenListPtr[0] = DCT_VAL_CATEGORY6;    
+    if ( DataValue > 0 )
+      TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT6_MIN);
+    else
+      TokenListPtr[1] = (0x010) + (AbsDataVal - DCT_VAL_CAT6_MIN);
+    tokens_added = 2;
+  } else if ( AbsDataVal <= 68 ) {
+    /* Bit 5 determines sign, Bit 0-4 the value */
+    TokenListPtr[0] = DCT_VAL_CATEGORY7;    
+    if ( DataValue > 0 )
+      TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT7_MIN);
+    else
+      TokenListPtr[1] = (0x20) + (AbsDataVal - DCT_VAL_CAT7_MIN);
+    tokens_added = 2;
+  } else if ( AbsDataVal <= 511 ) {
+    /* Bit 9 determines sign, Bit 0-8 the value */
+    TokenListPtr[0] = DCT_VAL_CATEGORY8;    
+    if ( DataValue > 0 )
+      TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT8_MIN);
+    else
+      TokenListPtr[1] = (0x200) + (AbsDataVal - DCT_VAL_CAT8_MIN);
+    tokens_added = 2;
+  } else {
+    TokenListPtr[0] = DCT_VAL_CATEGORY8;    
+    if ( DataValue > 0 )
+      TokenListPtr[1] = (511 - DCT_VAL_CAT8_MIN);
+    else
+      TokenListPtr[1] = (0x200) + (511 - DCT_VAL_CAT8_MIN);
+    tokens_added = 2;
+  }
+  
+  /* Return the total number of tokens added */
+  return tokens_added;
 }
 
 unsigned char TokenizeDctRunValue (unsigned char RunLength, 
@@ -220,9 +217,8 @@
   
   /* Values are tokenised as category value and a number of additional
      bits  that define the category.  */
-  if ( DataValue == 0 ) {
-    IssueWarning( "Bad Input to TokenizeDctRunValue" );
-  } else if ( AbsDataVal == 1 ) {   
+  if ( DataValue == 0 ) return 0;
+  if ( AbsDataVal == 1 ) {   
     /* Zero runs of 1-5 */
     if ( RunLength <= 5 ) {
       TokenListPtr[0] = DCT_RUN_CATEGORY1 + (RunLength - 1);  
@@ -270,7 +266,7 @@
     }
   } else  {
     tokens_added = 2;  /* ERROR */
-    IssueWarning( "Bad Input to TokenizeDctRunValue" );
+    /*IssueWarning( "Bad Input to TokenizeDctRunValue" );*/
   }
   
   /* Return the total number of tokens added */
@@ -388,8 +384,7 @@
   
   ogg_int32_t MvShift;
   ogg_int32_t MvModMask; 
-  ogg_uint32_t ReconPixelIndex = GetFragIndex(cpi->pb.recon_pixel_index_table,
-					      FragIndex);
+  ogg_uint32_t ReconPixelIndex = cpi->pb.recon_pixel_index_table[FragIndex];
   ogg_int32_t  AbsRefOffset;
   ogg_int32_t  AbsXOffset;             
   ogg_int32_t  AbsYOffset;
@@ -444,12 +439,10 @@
   
   if ( cpi->pb.CodingMode==CODE_GOLDEN_MV ) {
     ReconPtr1 = &cpi->
-      pb.GoldenFrame[GetFragIndex(cpi->pb.recon_pixel_index_table, 
-				  FragIndex)];
+      pb.GoldenFrame[cpi->pb.recon_pixel_index_table[FragIndex]];
   } else {
     ReconPtr1 = &cpi->
-      pb.LastFrameRecon[GetFragIndex(cpi->pb.recon_pixel_index_table, 
-				     FragIndex)];
+      pb.LastFrameRecon[cpi->pb.recon_pixel_index_table[FragIndex]];
   }
   
   ReconPtr1 += MVOffset;
@@ -489,8 +482,8 @@
   ogg_int32_t   MvDevisor;      /* Defines MV resolution (2 = 1/2
                                    pixel for Y or 4 = 1/4 for UV) */
 
-  new_ptr1 = &cpi->yuv1ptr[GetFragIndex(cpi->pb.pixel_index_table,FragIndex)]; 
-  old_ptr1 = &cpi->yuv0ptr[GetFragIndex(cpi->pb.pixel_index_table,FragIndex)];
+  new_ptr1 = &cpi->yuv1ptr[cpi->pb.pixel_index_table[FragIndex]]; 
+  old_ptr1 = &cpi->yuv0ptr[cpi->pb.pixel_index_table[FragIndex]];
   DctInputPtr	= cpi->DCTDataBuffer;
   
   /* Set plane specific values */
@@ -503,8 +496,7 @@
   }
 
   /* adjusted / filtered pointers */
-  FiltPtr = &cpi->ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
-					      FragIndex)];
+  FiltPtr = &cpi->ConvDestBuffer[cpi->pb.pixel_index_table[FragIndex]];
 
   if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
     /* Key frame so code block in INTRA mode. */
@@ -543,12 +535,10 @@
               ( cpi->pb.CodingMode==CODE_USING_GOLDEN ) ) {
     if ( cpi->pb.CodingMode==CODE_INTER_NO_MV ) {
       ReconPtr1 = &cpi->
-	pb.LastFrameRecon[GetFragIndex(cpi->pb.recon_pixel_index_table,
-				       FragIndex)];
+	pb.LastFrameRecon[cpi->pb.recon_pixel_index_table[FragIndex]];
     } else {
       ReconPtr1 = &cpi->
-	pb.GoldenFrame[GetFragIndex(cpi->pb.recon_pixel_index_table,
-				    FragIndex)];
+	pb.GoldenFrame[cpi->pb.recon_pixel_index_table[FragIndex]];
     }
 
     Sub8( FiltPtr, ReconPtr1, DctInputPtr, old_ptr1, new_ptr1, 
@@ -556,9 +546,7 @@
   } else if ( cpi->pb.CodingMode==CODE_INTRA ) {
     Sub8_128(FiltPtr, DctInputPtr, old_ptr1, new_ptr1, PixelsPerLine);
     
-  } else {
-    IssueWarning( "Illegal coding mode" );
-  }
+  } 
 
   /* Proceed to encode the data into the encode buffer if the encoder
      is enabled. */

<p><p>1.4       +13 -26    theora/lib/encode.c

Index: encode.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encode.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- encode.c	18 Sep 2002 08:56:56 -0000	1.3
+++ encode.c	20 Sep 2002 09:30:32 -0000	1.4
@@ -11,14 +11,14 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: encode.c,v 1.3 2002/09/18 08:56:56 xiphmont Exp $
+  last mod: $Id: encode.c,v 1.4 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
 #include "ogg/ogg.h"
 #include "encoder_internal.h"
 #include "encoder_lookup.h"
-#include "hufftables.h"
+#include "block_inline.h"
 
 #define PUL 8
 #define PU 4
@@ -99,9 +99,6 @@
     } 
   }
 
-  /* system state should be cleared here.... */
-  ClearSysState();
-  
   /* Return number of pixels coded */
   return coded_pixels;
 }
@@ -177,11 +174,11 @@
                      pb.HuffCodeLengthArray_VP3x[HuffIndex][Token] );
 
     /* If the token is followed by an extra bits token then code it */
-    if ( ExtraBitLengths_VP31[Token] > 0 ) {
+    if ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 ) {
       /* Add the bits to the encode holding buffer.  */
-      cpi->FrameBitCount += ExtraBitLengths_VP31[Token];
+      cpi->FrameBitCount += cpi->pb.ExtraBitLengths_VP3x[Token];
       oggpackB_write( opb, ExtraBitsToken, 
-		       (ogg_uint32_t)ExtraBitLengths_VP31[Token] );
+		       (ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );
     }
   }
   
@@ -257,11 +254,11 @@
                      pb.HuffCodeLengthArray_VP3x[HuffIndex][Token] );
 
     /* If the token is followed by an extra bits token then code it */
-    if ( ExtraBitLengths_VP31[Token] > 0 ) {
+    if ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 ) {
       /* Add the bits to the encode holding buffer. */
-      cpi->FrameBitCount += ExtraBitLengths_VP31[Token];
+      cpi->FrameBitCount += cpi->pb.ExtraBitLengths_VP3x[Token];
       oggpackB_write( opb, ExtraBitsToken, 
-		       (ogg_uint32_t)ExtraBitLengths_VP31[Token] );
+		       (ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );
     }
   }
   
@@ -449,9 +446,7 @@
       cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] = 
         cpi->RunLength;
       cpi->RunLength = 0;
-    } else {
-      IssueWarning("PackEOBRun : RunLength > 4095");
-    }
+    } 
     
   }
   
@@ -480,7 +475,7 @@
   
   /* Update record of tokens coded and where we are in this fragment. */
   /* Is there an extra bits token */
-  OneOrTwo= 1 + ( ExtraBitLengths_VP31[Token] > 0 ); 
+  OneOrTwo= 1 + ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 ); 
   /* Advance to the next real token. */
   cpi->FragTokens[FragmentNumber] += OneOrTwo;
         
@@ -527,11 +522,9 @@
   ogg_uint32_t	ErrorVal = 0;
   
   unsigned char * SrcDataPtr = 
-    &cpi->ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
-				      BlockIndex)];
+    &cpi->ConvDestBuffer[cpi->pb.pixel_index_table[BlockIndex]];
   unsigned char * RecDataPtr = 
-    &cpi->pb.LastFrameRecon[GetFragIndex(cpi->pb.recon_pixel_index_table,
-					 BlockIndex)];
+    &cpi->pb.LastFrameRecon[cpi->pb.recon_pixel_index_table[BlockIndex]];
   ogg_int32_t   SrcStride;
   ogg_int32_t   RecStride;
   
@@ -569,8 +562,6 @@
   ogg_int32_t FragIndex;
   ogg_uint32_t HuffIndex; /* Index to group of tables used to code a token */
 
-  ClearSysState();
-
   /* Reset the count of second order optimised tokens */
   cpi->OptimisedTokenCount = 0;
   
@@ -1011,8 +1002,6 @@
     
   }
         
-  ClearSysState();
-
   /* Return total number of coded pixels */
   return coded_pixels;
 }
@@ -1578,8 +1567,6 @@
     }
   }
 
-  ClearSysState();
-  
   /* Return number of pixels coded */
   return 0;
 }
@@ -1604,7 +1591,7 @@
    
   if ( i == Q_TABLE_SIZE ) {
     /* An invalid DCT value was specified.  */
-    IssueWarning( "Invalid Q Multiplier" );
+    /*IssueWarning( "Invalid Q Multiplier" );*/
     oggpackB_write( opb, 31, 6 );
   }
   

<p><p>1.4       +12 -21    theora/lib/encoder_internal.h

Index: encoder_internal.h
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encoder_internal.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- encoder_internal.h	18 Sep 2002 08:56:56 -0000	1.3
+++ encoder_internal.h	20 Sep 2002 09:30:32 -0000	1.4
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: encoder_internal.h,v 1.3 2002/09/18 08:56:56 xiphmont Exp $
+  last mod: $Id: encoder_internal.h,v 1.4 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
@@ -55,6 +55,8 @@
 #define MIN_BPB_FACTOR        0.3
 #define MAX_BPB_FACTOR        3.0
 
+#define MAX_MV_EXTENT 31  /* Max search distance in half pixel increments */
+
 typedef enum{       
         SCP_CONFIGURE_PP
 } SCP_SETTINGS;
@@ -186,7 +188,8 @@
   
   /* Block Thresholds. */
   ogg_uint32_t  PrimaryBlockThreshold;
-  
+  unsigned char LineSearchTripTresh;
+
   int   PAKEnabled;
   
   int   LevelThresh; 
@@ -198,11 +201,8 @@
   
   /* Threshold lookup tables */
   unsigned char SrfPakThreshTable[512];
-  unsigned char * SrfPakThreshTablePtr;
   unsigned char SrfThreshTable[512];
-  unsigned char * SrfThreshTablePtr;
   unsigned char SgcThreshTable[512];
-  unsigned char * SgcThreshTablePtr;
   
   /* Variables controlling S.A.D. break outs. */
   ogg_uint32_t GrpLowSadThresh;
@@ -233,13 +233,6 @@
 } PP_INSTANCE;
 
 
-typedef struct {
-  int bitsinremainder;    /* # of bits still used in remainder */
-  ogg_uint32_t remainder; /* remaining bits from original long */
-  unsigned char *position;/* character pointer position within data */
-  unsigned char *origin;  /* starting point of original data */
-} BITREADER;
-
 typedef enum{
   CODE_INTER_NO_MV        = 0x0, /* INTER prediction, (0,0) motion
                                     vector implied.  */
@@ -264,12 +257,7 @@
 } HUFF_ENTRY; 
 
 typedef struct PB_INSTANCE {
-  /***********************************************************************
-   Bitstream input and Output Pointers
-  ************************************************************************/
-
-  /* Current access points for input and output buffers */
-  BITREADER br;
+  oggpack_buffer opb;
 
   /***********************************************************************/
   /* Decoder and Frame Type Information */
@@ -283,9 +271,6 @@
   int           PostProcessEnabled;
   
   ogg_uint32_t  PostProcessingLevel;    /* Perform post processing */
-  ogg_uint32_t  ProcessorFrequency;     /* CPU frequency     */
-  ogg_uint32_t  CPUFree;
-  
   
   /* Frame Info */
   CODING_MODE   CodingMode;
@@ -457,6 +442,7 @@
   HUFF_ENTRY   **HuffRoot_VP3x;
   ogg_uint32_t **HuffCodeArray_VP3x;
   unsigned char **HuffCodeLengthArray_VP3x;
+  unsigned char *ExtraBitLengths_VP3x;
   
   /* Quantiser and rounding tables */
   ogg_int32_t    fp_quant_UV_coeffs[64];
@@ -696,6 +682,11 @@
 
 } YUV_INPUT_BUFFER_CONFIG;
 
+/*#define clamp255(x) (((ogg_int32_t)(x)&~0xff)?((ogg_int32_t)(x))>>31:(x))*/
+#define clamp255(val)  ( val<0 ? 0: ( val>255 ? 255:val ) )
 
 extern void ClearPPInstance(PP_INSTANCE *ppi);
 extern void InitPPInstance(PP_INSTANCE *ppi);
+extern int GetFrameType(PB_INSTANCE *pbi);
+
+

<p><p>1.3       +1 -37     theora/lib/encoder_lookup.h

Index: encoder_lookup.h
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encoder_lookup.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- encoder_lookup.h	18 Sep 2002 08:56:57 -0000	1.2
+++ encoder_lookup.h	20 Sep 2002 09:30:32 -0000	1.3
@@ -11,12 +11,10 @@
  ********************************************************************
 
   function: simple static lookups for VP3 frame encoder
-  last mod: $Id: encoder_lookup.h,v 1.2 2002/09/18 08:56:57 xiphmont Exp $
+  last mod: $Id: encoder_lookup.h,v 1.3 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
-#define MAX_MV_EXTENT 31  /* Max search distance in half pixel increments */
-
 ogg_uint32_t MvPattern[(MAX_MV_EXTENT * 2) + 1] = {   
   0x000000ff, 0x000000fd, 0x000000fb, 0x000000f9, 
   0x000000f7, 0x000000f5, 0x000000f3, 0x000000f1,
@@ -122,37 +120,3 @@
   15, 15, 15, 15, 15, 15, 15, 15
 };  
 
-
-ogg_uint32_t PriorKeyFrameWeight[KEY_FRAME_CONTEXT] = { 1,2,3,4,5 };
-
-/* Data structures controlling addition of residue blocks */
-ogg_uint32_t ResidueErrorThresh[Q_TABLE_SIZE] =  {    
-  750, 700, 650, 600, 590, 580, 570, 560, 
-  550, 540, 530, 520, 510, 500, 490, 480,  
-  470, 460, 450, 440, 430, 420, 410, 400, 
-  390, 380, 370, 360, 350, 340, 330, 320, 
-  310, 300, 290, 280, 270, 260, 250, 245, 
-  240, 235, 230, 225, 220, 215, 210, 205, 
-  200, 195, 190, 185, 180, 175, 170, 165,
-  160, 155, 150, 145, 140, 135, 130, 130 };
-ogg_uint32_t ResidueBlockFactor[Q_TABLE_SIZE] =  {    
-  3,   3,   3,   3,   3,   3,   3,   3,
-  3,   3,   3,   3,   3,   3,   3,   3,
-  3,   3,   3,   3,   3,   3,   3,   3,
-  3,   3,   3,   3,   3,   3,   3,   3,
-  2,   2,   2,   2,   2,   2,   2,   2,
-  2,   2,   2,   2,   2,   2,   2,   2,
-  2,   2,   2,   2,   2,   2,   2,   2,
-  2,   2,   2,   2,   2,   2,   2,   2 };
-
-/* Quantization zigzag pattern */
-ogg_uint32_t dequant_index[64] = {
-  0,  1,  8,  16,  9,  2,  3, 10,
-  17, 24, 32, 25, 18, 11,  4,  5,
-  12, 19, 26, 33, 40, 48, 41, 34,
-  27, 20, 13,  6,  7, 14, 21, 28,
-  35, 42, 49, 56, 57, 50, 43, 36, 
-  29, 22, 15, 23, 30, 37, 44, 51,
-  58, 59, 52, 45, 38, 31, 39, 46,
-  53, 60, 61, 54, 47, 55, 62, 63
-};

<p><p>1.3       +553 -6    theora/lib/frarray.c

Index: frarray.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/frarray.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- frarray.c	18 Sep 2002 08:56:57 -0000	1.2
+++ frarray.c	20 Sep 2002 09:30:32 -0000	1.3
@@ -11,12 +11,13 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: frarray.c,v 1.2 2002/09/18 08:56:57 xiphmont Exp $
+  last mod: $Id: frarray.c,v 1.3 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
 #include <ogg/ogg.h>
 #include "encoder_internal.h"
+#include "block_inline.h"
 
 ogg_uint32_t FrArrayCodeSBRun( CP_INSTANCE *cpi, ogg_uint32_t value ){
   ogg_uint32_t CodedVal = 0;
@@ -56,7 +57,7 @@
   }
   
   /* Add the bits to the encode holding buffer. */    
-  AddBitsToBuffer( cpi, CodedVal, (ogg_uint32_t)CodedBits );
+  oggpackB_write( &cpi->oggbuffer, CodedVal, (ogg_uint32_t)CodedBits );
   
   return CodedBits;
 }
@@ -98,7 +99,7 @@
  }
 
   /* Add the bits to the encode holding buffer. */    
-  AddBitsToBuffer( cpi, CodedVal, (ogg_uint32_t)CodedBits );
+  oggpackB_write( &cpi->oggbuffer, CodedVal, (ogg_uint32_t)CodedBits );
 
   return CodedBits;
 }
@@ -159,7 +160,7 @@
 
   /* Code list of partially coded Super-Block.  */
   val = cpi->PartiallyCodedFlags[0];
-  AddBitsToBuffer( cpi, (ogg_uint32_t)val, 1);
+  oggpackB_write( &cpi->oggbuffer, (ogg_uint32_t)val, 1);
   i = 0;
   while ( i < cpi->pb.SuperBlocks ) {
     run_count = 0;
@@ -182,7 +183,7 @@
   
   if ( i < cpi->pb.SuperBlocks ) {
     val = cpi->pb.SBFullyFlags[i];              
-    AddBitsToBuffer( cpi, (ogg_uint32_t)val, 1);
+    oggpackB_write( &cpi->oggbuffer, (ogg_uint32_t)val, 1);
     
     while ( i < cpi->pb.SuperBlocks ) {
       run_count = 0;
@@ -204,7 +205,7 @@
   if ( BListIndex > 0 ) {
     /* Code the block flags start value */
     val = cpi->BlockCodedFlags[0];
-    AddBitsToBuffer( cpi, (ogg_uint32_t)val, 1);
+    oggpackB_write( &cpi->oggbuffer, (ogg_uint32_t)val, 1);
     
     /* Now code the block flags. */
     for ( i = 0; i < BListIndex; ) {
@@ -219,5 +220,551 @@
       
     }
   }
+}
+
+static void FrArrayDeCodeInit(PB_INSTANCE *pbi){   
+  /* Initialise the decoding of a run.  */
+  pbi->bit_pattern = 0;
+  pbi->bits_so_far = 0; 
+}
+
+void GetNextBInit(PB_INSTANCE *pbi){
+  pbi->NextBit = oggpackB_read(&pbi->opb,1);
+
+  /* Read run length */
+  FrArrayDeCodeInit(pbi);               
+  while ( FrArrayDeCodeBlockRun( pbi, oggpackB_read(&pbi->opb,1), 
+				 &pbi->BitsLeft ) == 0 );
+}
+
+unsigned char GetNextBBit (PB_INSTANCE *pbi){
+  if ( !pbi->BitsLeft ){
+    /* Toggle the value.   */
+    pbi->NextBit = ( pbi->NextBit == 1 ) ? 0 : 1;
+
+    /* Read next run */
+    FrArrayDeCodeInit(pbi);
+    while ( FrArrayDeCodeBlockRun( pbi,oggpackB_read(&pbi->opb,1), 
+				   &pbi->BitsLeft ) == 0 );
+  }
+
+  /* Have  read a bit */
+  pbi->BitsLeft--;
+  
+  /* Return next bit value */
+  return pbi->NextBit;
+}
+
+void GetNextSbInit(PB_INSTANCE *pbi){
+  pbi->NextBit = oggpackB_read(&pbi->opb,1);
+  
+  /* Read run length */
+  FrArrayDeCodeInit(pbi);               
+  while ( FrArrayDeCodeSBRun( pbi,oggpackB_read(&pbi->opb,1), 
+			      &pbi->BitsLeft ) == 0 );
+}
+
+unsigned char GetNextSbBit (PB_INSTANCE *pbi){
+  if ( !pbi->BitsLeft ){
+    /* Toggle the value.   */
+    pbi->NextBit = ( pbi->NextBit == 1 ) ? 0 : 1;
+
+    /* Read next run */
+    FrArrayDeCodeInit(pbi);               
+    while ( FrArrayDeCodeSBRun( pbi, oggpackB_read(&pbi->opb,1), 
+				&pbi->BitsLeft ) == 0 );
+  }
+  
+  /* Have  read a bit */
+  pbi->BitsLeft--;
+  
+  /* Return next bit value */
+  return pbi->NextBit;
+}
+
+void GetNextMbInit(PB_INSTANCE *pbi){
+  pbi->NextBit = oggpackB_read(&pbi->opb,1);
+  pbi->BitsLeft = 0;
+  
+  /* Read run length */
+  FrArrayDeCodeInit(pbi);               
+  while ( FrArrayDeCodeMBRun( pbi,oggpackB_read(&pbi->opb,1), 
+			      &pbi->BitsLeft ) == 0 );
+}
+
+unsigned char GetNextMbBit (PB_INSTANCE *pbi){
+  if ( !pbi->BitsLeft ){
+    /* Toggle the value. */
+    pbi->NextBit = ( pbi->NextBit == 1 ) ? 0 : 1;
+    
+    /* Read next run */
+    FrArrayDeCodeInit(pbi);       
+    while ( FrArrayDeCodeMBRun( pbi, oggpackB_read(&pbi->opb,1), 
+				&pbi->BitsLeft ) == 0 );
+  }
+  
+  /* Decrement bits left in run counter */
+  pbi->BitsLeft--;
+  
+  /* Return next bit value */
+  return pbi->NextBit;
+}
+
+void ReadBlockPatternInit (PB_INSTANCE *pbi){
+  pbi->BlockPatternPredictor = 0;
+}
+
+unsigned char ReadNextBlockPattern (PB_INSTANCE *pbi){
+  unsigned char BlockPattern = 0;
+  unsigned char Bitpattern = 0;
+  ogg_uint32_t BitCount = 3;
+
+  /* Read three bits and test to see if we have a valid token. */
+  Bitpattern = oggpackB_read(&pbi->opb, 3);
+  
+  /* Test pattern to see if is a valid token. */
+  BlockPattern = BlockDecode1[pbi->BlockPatternPredictor][Bitpattern];
+  
+  /* if pattern was not a valid token */
+  if ( !BlockPattern ){
+    BitCount++;
+    Bitpattern = (Bitpattern << 1) + oggpackB_read(&pbi->opb,1);
+    
+    /* Test pattern to see if is a valid token. */
+    BlockPattern = BlockDecode2[pbi->BlockPatternPredictor][Bitpattern];
+    
+    if ( !BlockPattern ){
+      BitCount++;
+      Bitpattern = (Bitpattern << 1) + oggpackB_read(&pbi->opb,1);
+      BlockPattern = BlockDecode3[pbi->BlockPatternPredictor][Bitpattern];
+    }
+  }
+  
+  /* Update the entropy predictor for next time. */
+  pbi->BlockPatternPredictor = BPPredictor[BlockPattern];
+  return BlockPattern;
+
+}
+void QuadDecodeDisplayFragments ( PB_INSTANCE *pbi ){
+  ogg_uint32_t  SB, MB, B;
+  int    DataToDecode; 
+
+  ogg_int32_t   dfIndex;
+  ogg_uint32_t  MBIndex = 0;
+
+  /* Reset various data structures common to key frames and inter frames. */
+  pbi->CodedBlockIndex = 0;
+  memset ( pbi->display_fragments, 0, pbi->UnitFragments );
+
+  /* For "Key frames" mark all blocks as coded and return. */
+  /* Else initialise the ArrayPtr array to 0 (all blocks uncoded by default) */
+  if ( GetFrameType(pbi) == BASE_FRAME ) {
+    memset( pbi->SBFullyFlags, 1, pbi->SuperBlocks );
+    memset( pbi->SBCodedFlags, 1, pbi->SuperBlocks );
+        memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );
+  }else{
+    memset( pbi->SBFullyFlags, 0, pbi->SuperBlocks );
+    memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );
+    
+    /* Un-pack the list of partially coded Super-Blocks */
+    GetNextSbInit(pbi);
+    for( SB = 0; SB < pbi->SuperBlocks; SB++){
+      pbi->SBCodedFlags[SB] = GetNextSbBit (pbi);
+    }
+    
+    /* Scan through the list of super blocks.  Unless all are marked
+       as partially coded we have more to do. */
+    DataToDecode = 0; 
+    for ( SB=0; SB<pbi->SuperBlocks; SB++ ) {
+      if ( !pbi->SBCodedFlags[SB] ) {
+	DataToDecode = 1;
+	break;
+      }
+    }
+
+    /* Are there further block map bits to decode ? */
+    if ( DataToDecode ) {
+      /* Un-pack the Super-Block fully coded flags. */
+      GetNextSbInit(pbi);
+      for( SB = 0; SB < pbi->SuperBlocks; SB++) {
+	/* Skip blocks already marked as partially coded */
+	while( (SB < pbi->SuperBlocks) && pbi->SBCodedFlags[SB] )  
+	  SB++;
+	
+	if ( SB < pbi->SuperBlocks ) {
+	  pbi->SBFullyFlags[SB] = GetNextSbBit (pbi);
+	  
+	  if ( pbi->SBFullyFlags[SB] )       /* If SB is fully coded. */
+	    pbi->SBCodedFlags[SB] = 1;       /* Mark the SB as coded */
+	}
+      }
+    }
+    
+    /* Scan through the list of coded super blocks.  If at least one
+       is marked as partially coded then we have a block list to
+       decode. */
+    for ( SB=0; SB<pbi->SuperBlocks; SB++ ) {
+      if ( pbi->SBCodedFlags[SB] && !pbi->SBFullyFlags[SB] ) {
+	/* Initialise the block list decoder. */
+	GetNextBInit(pbi);
+	break;
+      }
+    }
+  }
+  
+  /* Decode the block data from the bit stream. */
+  for ( SB=0; SB<pbi->SuperBlocks; SB++ ){
+    for ( MB=0; MB<4; MB++ ){
+      /* If MB is in the frame */
+      if ( QuadMapToMBTopLeft(pbi->BlockMap, SB,MB) >= 0 ){
+	/* Only read block level data if SB was fully or partially coded */
+	if ( pbi->SBCodedFlags[SB] ) {
+	  for ( B=0; B<4; B++ ){
+	    /* If block is valid (in frame)... */
+	    dfIndex = QuadMapToIndex1( pbi->BlockMap, SB, MB, B );
+	    if ( dfIndex >= 0 ){
+	      if ( pbi->SBFullyFlags[SB] )
+		pbi->display_fragments[dfIndex] = 1;
+	      else
+		pbi->display_fragments[dfIndex] = GetNextBBit(pbi);
+	      
+	      /* Create linear list of coded block indices */
+	      if ( pbi->display_fragments[dfIndex] ) {
+		pbi->MBCodedFlags[MBIndex] = 1;
+		pbi->CodedBlockList[pbi->CodedBlockIndex] = dfIndex;
+		pbi->CodedBlockIndex++;
+	      }
+	    }
+	  }
+	}
+	MBIndex++;
+	
+      }
+    }
+  }
+}
+
+int FrArrayDeCodeMBRun(  PB_INSTANCE *pbi, ogg_uint32_t bit_value, 
+			 ogg_int32_t * run_value ){
+  int ret_val = 0;
+
+  /* Add in the new bit value. */
+  pbi->bits_so_far++;
+  pbi->bit_pattern = (pbi->bit_pattern << 1) + (bit_value & 1);
+        
+  /* Coding scheme:
+     Codeword                RunLength
+     0                           1
+     10                          2
+     110x                       3-4
+     1110xx                     5-8
+     11110xxx                   9-16
+     111110xxxx                17-32
+     1111110xxxxx              33-64
+     11111110xxxxxx            65-128
+     111111110xxxxxxx         129-256
+     111111111                  256 repeats
+  */
+  switch ( pbi->bits_so_far ){
+  case 1:  
+    if ( pbi->bit_pattern == 0 ){
+      ret_val = 1;
+      *run_value += 1;                             
+    }
+    break; 
+    
+  case 2:
+    /* Bit 1 clear */
+    if ( pbi->bit_pattern == 2 ){
+      ret_val = 1;
+      *run_value += 2;                             
+    }
+    break; 
+        
+  case 4:
+    /* Bit 1 clear */
+    if ( !(pbi->bit_pattern & 0x0002) ){
+      ret_val = 1;
+      *run_value += (pbi->bit_pattern & 0x0001) + 3;
+    }
+    break; 
+             
+  case 6:
+    /* Bit 2 clear */
+    if ( !(pbi->bit_pattern & 0x0004) ){
+      ret_val = 1;
+      *run_value += (pbi->bit_pattern & 0x0003) + 5;   
+    }
+    break; 
+    
+  case 8:
+    /* Bit 3 clear */
+    if ( !(pbi->bit_pattern & 0x0008) ){
+      ret_val = 1;
+      *run_value += (pbi->bit_pattern & 0x0007) + 9;
+    }
+    break; 
+    
+    /* This token is a special case repeat token and does not
+       terminate the run */
+  case 9:
+    if ( pbi->bit_pattern == 0x01FF ){
+      ret_val = 0;
+      *run_value += 256;                             
+      
+      /* Reset the bit counter and pattern. */
+      FrArrayDeCodeInit(pbi);
+    }
+    break;
+
+  case 10:
+    /* Bit 4 clear*/
+    if ( !(pbi->bit_pattern & 0x0010) ) {
+      ret_val = 1;
+      *run_value += (pbi->bit_pattern & 0x000F) + 17;
+    }
+    break; 
+    
+  case 12:
+    /* Bit 5 clear */
+    if ( !(pbi->bit_pattern & 0x0020) ){
+      ret_val = 1;
+      *run_value += (pbi->bit_pattern & 0x001F) + 33; 
+    }
+    break; 
+
+  case 14:
+    /* Bit 6 clear */
+    if ( !(pbi->bit_pattern & 0x0040) ) {
+      ret_val = 1;
+      *run_value += (pbi->bit_pattern & 0x003F) + 65; 
+    }
+    break; 
+    
+  case 16:
+    /* Bit 7 clear */
+    if ( !(pbi->bit_pattern & 0x0080) ) {
+      ret_val = 1;
+      *run_value += (pbi->bit_pattern & 0x007F) + 129; 
+    }
+    break; 
+    
+  default:
+    ret_val = 0;
+    break;
+  }
+  
+  return ret_val;
+}
+
+int FrArrayDeCodeSBRun (PB_INSTANCE *pbi, ogg_uint32_t bit_value, 
+			ogg_int32_t * run_value ){
+  int ret_val = 0;
+  
+  /* Add in the new bit value. */
+  pbi->bits_so_far++;
+  pbi->bit_pattern = (pbi->bit_pattern << 1) + (bit_value & 1);
+  
+  /* Coding scheme:
+     Codeword            RunLength
+     0                       1
+     10x                    2-3
+     110x                   4-5
+     1110xx                 6-9
+     11110xxx              10-17
+     111110xxxx            18-33
+     111111xxxxxxxxxxxx    34-4129
+  */
+
+  switch ( pbi->bits_so_far ){
+  case 1:  
+    if ( pbi->bit_pattern == 0 ){
+      ret_val = 1;
+      *run_value = 1;                             
+    }
+    break; 
+
+  case 3:
+    /* Bit 1 clear */
+    if ( !(pbi->bit_pattern & 0x0002) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0001) + 2; 
+    }
+    break; 
+    
+  case 4:
+    /* Bit 1 clear */
+    if ( !(pbi->bit_pattern & 0x0002) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0001) + 4;
+    }
+    break; 
+    
+  case 6:
+    /* Bit 2 clear */
+    if ( !(pbi->bit_pattern & 0x0004) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0003) + 6;
+    }
+    break; 
+    
+  case 8:
+    /* Bit 3 clear */
+    if ( !(pbi->bit_pattern & 0x0008) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0007) + 10; 
+    }
+    break; 
+          
+  case 10:
+    /* Bit 4 clear */
+    if ( !(pbi->bit_pattern & 0x0010) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x000F) + 18; 
+    }
+    break; 
+    
+  case 18:
+    ret_val = 1;
+    *run_value = (pbi->bit_pattern & 0x0FFF) + 34;                             
+    break; 
+    
+  default:
+    ret_val = 0;
+    break;
+  }
+  
+  return ret_val;
+}
+
+int FrArrayDeCodeBlockRun(  PB_INSTANCE *pbi, ogg_uint32_t bit_value, 
+			    ogg_int32_t * run_value ){
+  int  ret_val = 0;
+  
+  /* Add in the new bit value. */
+  pbi->bits_so_far++;
+  pbi->bit_pattern = (pbi->bit_pattern << 1) + (bit_value & 1);
+  
+  /* Coding scheme:
+     Codeword           RunLength
+     0x                    1-2
+     10x                   3-4
+     110x                  5-6
+     1110xx                7-10
+     11110xx              11-14
+     11111xxxx            15-30 	
+  */
+
+  switch ( pbi->bits_so_far ){
+  case 2: 
+    /* If bit 1 is clear */
+    if ( !(pbi->bit_pattern & 0x0002) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0001) + 1;
+    }           
+    break;      
+    
+  case 3:  
+    /* If bit 1 is clear */
+    if ( !(pbi->bit_pattern & 0x0002) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0001) + 3;
+    }           
+    break;      
+    
+  case 4:
+    /* If bit 1 is clear */
+    if ( !(pbi->bit_pattern & 0x0002) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0001) + 5;
+    }           
+    break;      
+    
+  case 6:
+    /* If bit 2 is clear */
+    if ( !(pbi->bit_pattern & 0x0004) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0003) + 7;
+    }           
+    break;      
+    
+  case 7:
+    /* If bit 2 is clear */
+    if ( !(pbi->bit_pattern & 0x0004) ){
+      ret_val = 1;
+      *run_value = (pbi->bit_pattern & 0x0003) + 11;
+    }           
+    break;      
+    
+  case 9:
+    ret_val = 1;
+    *run_value = (pbi->bit_pattern & 0x000F) + 15;
+    break;      
+  }
+  
+  return ret_val;
+}
+
+CODING_MODE FrArrayUnpackMode(PB_INSTANCE *pbi){
+  /* Coding scheme:
+     Token                      Codeword           Bits
+     Entry   0 (most frequent)  0                   1
+     Entry   1       	        10 	            2
+     Entry   2       	        110 		    3
+     Entry   3       	        1110 		    4
+     Entry   4       	        11110 		    5
+     Entry   5       	        111110 	            6
+     Entry   6       	        1111110 	    7
+     Entry   7       	        1111111 	    7
+  */
+
+  /* Initialise the decoding. */
+  pbi->bit_pattern = 0;
+  pbi->bits_so_far = 0; 
+  
+  pbi->bit_pattern = oggpackB_read(&pbi->opb,1);
+  
+  /* Do we have a match */
+  if ( pbi->bit_pattern == 0 )
+    return (CODING_MODE)0;
+  
+  /* Get the next bit */
+  pbi->bit_pattern = (pbi->bit_pattern << 1) | oggpackB_read(&pbi->opb,1);
+
+  /* Do we have a match */
+  if ( pbi->bit_pattern == 0x0002 )
+    return (CODING_MODE)1;
+  
+  pbi->bit_pattern = (pbi->bit_pattern << 1) | oggpackB_read(&pbi->opb,1);
+  
+  /* Do we have a match  */
+  if ( pbi->bit_pattern == 0x0006 )
+    return (CODING_MODE)2;
+  
+  pbi->bit_pattern = (pbi->bit_pattern << 1) | oggpackB_read(&pbi->opb,1);
+  
+  /* Do we have a match */
+  if ( pbi->bit_pattern == 0x000E )
+    return (CODING_MODE)3;
+  
+  pbi->bit_pattern = (pbi->bit_pattern << 1) | oggpackB_read(&pbi->opb,1);
+  
+  /* Do we have a match */
+  if ( pbi->bit_pattern == 0x001E )
+    return (CODING_MODE)4;
+  
+  pbi->bit_pattern = (pbi->bit_pattern << 1) | oggpackB_read(&pbi->opb,1);
+  
+  /* Do we have a match */
+  if ( pbi->bit_pattern == 0x003E )
+    return (CODING_MODE)5;
+  
+  pbi->bit_pattern = (pbi->bit_pattern << 1) | oggpackB_read(&pbi->opb,1);
+  
+  /* Do we have a match */
+  if ( pbi->bit_pattern == 0x007E )
+    return (CODING_MODE)6;
+  else
+    return (CODING_MODE)7;
 }
 

<p><p>1.2       +28 -25    theora/lib/huffman.c

Index: huffman.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/huffman.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- huffman.c	18 Sep 2002 08:56:57 -0000	1.1
+++ huffman.c	20 Sep 2002 09:30:32 -0000	1.2
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: huffman.c,v 1.1 2002/09/18 08:56:57 xiphmont Exp $
+  last mod: $Id: huffman.c,v 1.2 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
@@ -186,15 +186,42 @@
   }
 }
 
+void ClearHuffmanSet( PB_INSTANCE *pbi ){    
+  int i;
+  
+  HUFF_ENTRY **HuffRoot = pbi->HuffRoot_VP3x ;
+  
+  for ( i = 0; i < NUM_HUFF_TABLES; i++ ){
+    if (pbi->HuffRoot_VP3x[i]) DestroyHuffTree(pbi->HuffRoot_VP3x[i]);
+    if (pbi->HuffCodeArray_VP3x[i]) 
+      _ogg_free (pbi->HuffCodeArray_VP3x[i]);
+    if (pbi->HuffCodeLengthArray_VP3x[i]) 
+      _ogg_free (pbi->HuffCodeLengthArray_VP3x[i]);
+  }
+
+  if(pbi->HuffRoot_VP3x)_ogg_free(pbi->HuffRoot_VP3x);
+  if (pbi->HuffCodeArray_VP3x) 
+    _ogg_free (pbi->HuffCodeArray_VP3x);
+  if (pbi->HuffCodeLengthArray_VP3x) 
+    _ogg_free (pbi->HuffCodeLengthArray_VP3x);
+  
+  pbi->HuffRoot_VP3x=NULL;
+  pbi->HuffCodeArray_VP3x=NULL;
+  pbi->HuffCodeLengthArray_VP3x=NULL;
+}
+
 void InitHuffmanSet( PB_INSTANCE *pbi ){
   int i;
 
+  ClearHuffmanSet(pbi);
+
   pbi->HuffRoot_VP3x = 
     _ogg_calloc(NUM_HUFF_TABLES,sizeof(*pbi->HuffRoot_VP3x));
   pbi->HuffCodeArray_VP3x = 
     _ogg_calloc(NUM_HUFF_TABLES,sizeof(*pbi->HuffCodeArray_VP3x));
   pbi->HuffCodeLengthArray_VP3x = 
     _ogg_calloc(NUM_HUFF_TABLES,sizeof(*pbi->HuffCodeLengthArray_VP3x));
+  pbi->ExtraBitLengths_VP3x = ExtraBitLengths_VP31;
   
   for ( i = 0; i < NUM_HUFF_TABLES; i++ ){
     pbi->HuffCodeArray_VP3x[i] = 
@@ -208,29 +235,5 @@
                       pbi->HuffCodeLengthArray_VP3x[i],
                       i, FrequencyCounts_VP31[i]);
   }
-}
-
-void DestroyHuffmanSet( PB_INSTANCE *pbi ){    
-  int i;
-  
-  HUFF_ENTRY **HuffRoot = pbi->HuffRoot_VP3x ;
-  
-  for ( i = 0; i < NUM_HUFF_TABLES; i++ ){
-    if (pbi->HuffRoot_VP3x[i]) DestroyHuffTree(pbi->HuffRoot_VP3x[i]);
-    if (pbi->HuffCodeArray_VP3x[i]) 
-      _ogg_free (pbi->HuffCodeArray_VP3x[i]);
-    if (pbi->HuffCodeLengthArray_VP3x[i]) 
-      _ogg_free (pbi->HuffCodeLengthArray_VP3x[i]);
-  }
-
-  if(pbi->HuffRoot_VP3x)_ogg_free(pbi->HuffRoot_VP3x);
-  if (pbi->HuffCodeArray_VP3x) 
-    _ogg_free (pbi->HuffCodeArray_VP3x);
-  if (pbi->HuffCodeLengthArray_VP3x) 
-    _ogg_free (pbi->HuffCodeLengthArray_VP3x);
-  
-  pbi->HuffRoot_VP3x=NULL;
-  pbi->HuffCodeArray_VP3x=NULL;
-  pbi->HuffCodeLengthArray_VP3x=NULL;
 }
 

<p><p>1.2       +2 -2      theora/lib/idct.c

Index: idct.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/idct.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- idct.c	18 Sep 2002 08:56:57 -0000	1.1
+++ idct.c	20 Sep 2002 09:30:32 -0000	1.2
@@ -11,13 +11,13 @@
  ********************************************************************
 
   function:
-  last mod: $Id: idct.c,v 1.1 2002/09/18 08:56:57 xiphmont Exp $
+  last mod: $Id: idct.c,v 1.2 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
 #include <ogg/ogg.h>
 #include "encoder_internal.h"
-#include "encoder_lookup.h"
+#include "quant_lookup.h"
 
 #define IdctAdjustBeforeShift 8
 #define xC1S7 64277

<p><p>1.3       +25 -47    theora/lib/mcomp.c

Index: mcomp.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/mcomp.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- mcomp.c	18 Sep 2002 08:56:57 -0000	1.2
+++ mcomp.c	20 Sep 2002 09:30:32 -0000	1.3
@@ -11,16 +11,13 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: mcomp.c,v 1.2 2002/09/18 08:56:57 xiphmont Exp $
+  last mod: $Id: mcomp.c,v 1.3 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
 #include <stdio.h>
 #include <ogg/ogg.h>
 #include "encoder_internal.h"
-#include "encoder_lookup.h"
-
-//#define NEW_ERROR_METRIC
 
 /* Initialises motion compentsation. */
 void InitMotionCompensation ( CP_INSTANCE *cpi ){
@@ -358,9 +355,7 @@
   if ( cpi->pb.display_fragments[LocalFragIndex] ) 
     IntraError += 
       GetIntraError(&cpi->
-		    ConvDestBuffer[GetFragIndex(cpi->
-						pb.pixel_index_table,
-						LocalFragIndex)], 
+		    ConvDestBuffer[cpi->pb.pixel_index_table[LocalFragIndex]], 
                     PixelsPerLine );
   
 
@@ -368,24 +363,21 @@
   if ( cpi->pb.display_fragments[LocalFragIndex] ) 
     IntraError += 
       GetIntraError(&cpi->
-		    ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
-						LocalFragIndex)], 
+		    ConvDestBuffer[cpi->pb.pixel_index_table[LocalFragIndex]], 
                     PixelsPerLine );
   
   LocalFragIndex = FragIndex + cpi->pb.HFragments;
   if ( cpi->pb.display_fragments[LocalFragIndex] )
     IntraError += 
-      cGetIntraError(&cpi->
-		     ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
-						 LocalFragIndex)], 
+      GetIntraError(&cpi->
+		     ConvDestBuffer[cpi->pb.pixel_index_table[LocalFragIndex]],
                      PixelsPerLine );
 
   LocalFragIndex++;
   if ( cpi->pb.display_fragments[LocalFragIndex] )
     IntraError += 
       GetIntraError(&cpi->
-		    ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
-						LocalFragIndex)], 
+		    ConvDestBuffer[cpi->pb.pixel_index_table[LocalFragIndex]], 
                     PixelsPerLine );
   
   return IntraError;
@@ -409,11 +401,11 @@
   unsigned char * RefPtr1;
   
   /* Work out pixel offset into source buffer. */
-  PixelIndex = GetFragIndex(cpi->pb.pixel_index_table,LocalFragIndex);
+  PixelIndex = cpi->pb.pixel_index_table[LocalFragIndex];
   
   /* Work out the pixel offset in reference buffer for the default
      motion vector */
-  RefPixelIndex = GetFragIndex(cpi->pb.recon_pixel_index_table,LocalFragIndex);
+  RefPixelIndex = cpi->pb.recon_pixel_index_table[LocalFragIndex];
   RefPixelOffset = ((LastYMV/2) * RefPixelsPerLine) + (LastXMV/2);
 
   /* Work out the second reference pointer offset. */
@@ -436,41 +428,38 @@
   if ( cpi->pb.display_fragments[LocalFragIndex] ) {
     SrcPtr1 = &SrcPtr[PixelIndex];
     RefPtr1 = &RefPtr[RefPixelIndex + RefPixelOffset];
-    InterError += GetInterError( SrcPtr1, RefPtr1, 
+    InterError += GetInterErr( SrcPtr1, RefPtr1, 
                                  &RefPtr1[RefPtr2Offset], PixelsPerLine );
   }
   
   LocalFragIndex++;
   if ( cpi->pb.display_fragments[LocalFragIndex] ) {
-    PixelIndex = GetFragIndex(cpi->pb.pixel_index_table,LocalFragIndex);
-    RefPixelIndex = GetFragIndex(cpi->pb.recon_pixel_index_table,
-				 LocalFragIndex);
+    PixelIndex = cpi->pb.pixel_index_table[LocalFragIndex];
+    RefPixelIndex = cpi->pb.recon_pixel_index_table[LocalFragIndex];
     SrcPtr1 = &SrcPtr[PixelIndex];
     RefPtr1 = &RefPtr[RefPixelIndex + RefPixelOffset];
-    InterError += GetInterError( SrcPtr1, RefPtr1, 
+    InterError += GetInterErr( SrcPtr1, RefPtr1, 
                                  &RefPtr1[RefPtr2Offset], PixelsPerLine );
     
   }
 
   LocalFragIndex = FragIndex + cpi->pb.HFragments;
   if ( cpi->pb.display_fragments[LocalFragIndex] ) {
-    PixelIndex = GetFragIndex(cpi->pb.pixel_index_table,LocalFragIndex);
-    RefPixelIndex = GetFragIndex(cpi->pb.recon_pixel_index_table,
-				 LocalFragIndex);
+    PixelIndex = cpi->pb.pixel_index_table[LocalFragIndex];
+    RefPixelIndex = cpi->pb.recon_pixel_index_table[LocalFragIndex];
     SrcPtr1 = &SrcPtr[PixelIndex];
     RefPtr1 = &RefPtr[RefPixelIndex + RefPixelOffset];
-    InterError += GetInterError( SrcPtr1, RefPtr1, 
+    InterError += GetInterErr( SrcPtr1, RefPtr1, 
                                  &RefPtr1[RefPtr2Offset], PixelsPerLine );
   }
   
   LocalFragIndex++;
   if ( cpi->pb.display_fragments[LocalFragIndex] ) {
-    PixelIndex = GetFragIndex(cpi->pb.pixel_index_table,LocalFragIndex);
-    RefPixelIndex = GetFragIndex(cpi->pb.recon_pixel_index_table,
-				 LocalFragIndex);
+    PixelIndex = cpi->pb.pixel_index_table[LocalFragIndex];
+    RefPixelIndex = cpi->pb.recon_pixel_index_table[LocalFragIndex];
     SrcPtr1 = &SrcPtr[PixelIndex];
     RefPtr1 = &RefPtr[RefPixelIndex + RefPixelOffset];
-    InterError += GetInterError( SrcPtr1, RefPtr1, 
+    InterError += GetInterErr( SrcPtr1, RefPtr1, 
                                  &RefPtr1[RefPtr2Offset], PixelsPerLine );
   }
   return InterError;
@@ -519,15 +508,13 @@
     cpi->pb.display_fragments[FragIndex + cpi->pb.HFragments + 1];
   
   /* Set up the source pointers for the four source blocks.  */
-  SrcPtr[0] = &cpi->
-    ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,FragIndex)];
+  SrcPtr[0] = &cpi->ConvDestBuffer[cpi->pb.pixel_index_table[FragIndex]];
   SrcPtr[1] = SrcPtr[0] + 8;
   SrcPtr[2] = SrcPtr[0] + (PixelsPerLine * 8);
   SrcPtr[3] = SrcPtr[2] + 8;
 
   /* Set starting reference point for search. */
-  RefPtr = &RefFramePtr[GetFragIndex(cpi->
-				     pb.recon_pixel_index_table,FragIndex)];
+  RefPtr = &RefFramePtr[cpi->pb.recon_pixel_index_table[FragIndex]];
   
   /* Check the 0,0 candidate. */
   if ( MBlockDispFrags[0] ) {
@@ -661,8 +648,6 @@
   MV->x += cpi->HalfPixelXOffset[BestHalfOffset];
   MV->y += cpi->HalfPixelYOffset[BestHalfOffset];
 
-  ClearSysState();
-  
   /* Get the error score for the chosen 1/2 pixel offset as a variance. */
   InterMVError = GetMBInterError( cpi, cpi->ConvDestBuffer, RefFramePtr, 
                                   FragIndex, MV->x, MV->y, PixelsPerLine );
@@ -712,13 +697,12 @@
   
   /* Set up the source pointers for the four source blocks. */
   SrcPtr[0] = &cpi->
-    ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,FragIndex)];
+    ConvDestBuffer[cpi->pb.pixel_index_table[FragIndex]];
   SrcPtr[1] = SrcPtr[0] + 8;
   SrcPtr[2] = SrcPtr[0] + (PixelsPerLine * 8);
   SrcPtr[3] = SrcPtr[2] + 8;
 
-  RefPtr = &RefFramePtr[GetFragIndex(cpi->
-				     pb.recon_pixel_index_table,FragIndex)];
+  RefPtr = &RefFramePtr[cpi->pb.recon_pixel_index_table[FragIndex]];
   RefPtr = RefPtr - ((MAX_MV_EXTENT/2) * cpi->
                      pb.Configuration.YStride) - (MAX_MV_EXTENT/2);
 
@@ -853,10 +837,9 @@
   
   /* Set up the source pointer for the block. */
   SrcPtr = &cpi->
-    ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,FragIndex)];
+    ConvDestBuffer[cpi->pb.pixel_index_table[FragIndex]];
  
-  RefPtr = &RefFramePtr[GetFragIndex(cpi->
-				     pb.recon_pixel_index_table,FragIndex)];
+  RefPtr = &RefFramePtr[cpi->pb.recon_pixel_index_table[FragIndex]];
   RefPtr = RefPtr - ((MAX_MV_EXTENT/2) * 
                      cpi->pb.Configuration.YStride) - (MAX_MV_EXTENT/2);
   
@@ -914,13 +897,8 @@
   /* Get the variance score at the chosen offset */
   RefDataPtr2 = BestBlockPtr + cpi->HalfPixelRef2Offset[BestHalfOffset];
   
-#ifndef NEW_ERROR_METRIC
-  InterMVError = 
-    GetInterError( SrcPtr, BestBlockPtr, RefDataPtr2, PixelsPerLine );
-#else
   InterMVError = 
-    GetInterDCTErr(cpi, SrcPtr, BestBlockPtr, RefDataPtr2, PixelsPerLine );
-#endif
+    GetInterErr( SrcPtr, BestBlockPtr, RefDataPtr2, PixelsPerLine );
   
   /* Return score of best matching block. */
   return InterMVError;

<p><p>1.4       +4 -3      theora/lib/misc_common.c

Index: misc_common.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/misc_common.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- misc_common.c	18 Sep 2002 08:56:57 -0000	1.3
+++ misc_common.c	20 Sep 2002 09:30:32 -0000	1.4
@@ -11,12 +11,13 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: misc_common.c,v 1.3 2002/09/18 08:56:57 xiphmont Exp $
+  last mod: $Id: misc_common.c,v 1.4 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
 #include <ogg/ogg.h>
 #include "encoder_internal.h"
+#include "block_inline.h"
 
 #define FIXED_Q	                150
 #define MAX_UP_REG_LOOPS        2    
@@ -313,7 +314,7 @@
     /* We are only interested in updated fragments. */
     if ( cpi->extra_fragments[i] ) {
       /* Get the start index for the fragment. */
-      PixelIndex = GetFragIndex(cpi->pb.pixel_index_table, i);
+      PixelIndex = cpi->pb.pixel_index_table[i];
       SrcPtr = &cpi->yuv1ptr[PixelIndex];
       DestPtr = &cpi->ConvDestBuffer[PixelIndex];
       
@@ -335,7 +336,7 @@
     /* We are only interested in updated fragments. */
     if ( cpi->extra_fragments[i] ) {
       /* Get the start index for the fragment. */
-      PixelIndex = GetFragIndex(cpi->pb.pixel_index_table, i);
+      PixelIndex = cpi->pb.pixel_index_table[i];
       SrcPtr = &cpi->yuv1ptr[PixelIndex];
       DestPtr = &cpi->ConvDestBuffer[PixelIndex];
       

<p><p>1.2       +877 -2    theora/lib/pp.c

Index: pp.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/pp.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- pp.c	18 Sep 2002 08:56:57 -0000	1.1
+++ pp.c	20 Sep 2002 09:30:32 -0000	1.2
@@ -11,13 +11,32 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: pp.c,v 1.1 2002/09/18 08:56:57 xiphmont Exp $
+  last mod: $Id: pp.c,v 1.2 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <ogg/ogg.h>
 #include "encoder_internal.h"
+#include "pp.h"
+#include "quant_lookup.h"
+
+#define MAX(a, b) ((a>b)?a:b)
+#define MIN(a, b) ((a<b)?a:b)
+#define PP_QUALITY_THRESH   49
+
+ogg_int32_t SharpenModifier[ Q_TABLE_SIZE ] =
+{  -12, -11, -10, -10,  -9,  -9,  -9,  -9,
+    -6,  -6,  -6,  -6,  -6,  -6,  -6,  -6, 
+    -4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,
+    -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,
+    -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,
+    0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0
+};
+
+static ogg_uint32_t *DeringModifierV1=DcQuantScaleV1;
 
 void PClearFrameInfo(PP_INSTANCE * ppi){
   int i;
@@ -66,7 +85,7 @@
   
 }
 
-void PAllocateFrameInfo(PP_INSTANCE * ppi){
+void PInitFrameInfo(PP_INSTANCE * ppi){
   int i;
   PClearFrameInfo(ppi);
 
@@ -151,3 +170,859 @@
   
   ppi->MaxLineSearchLen = MAX_SEARCH_LINE_LEN;
 }
+
+static void DeringBlockStrong(PB_INSTANCE *pbi, 
+                       unsigned char *SrcPtr,
+                       unsigned char *DstPtr,
+                       ogg_int32_t Pitch,
+                       ogg_uint32_t FragQIndex,
+                       ogg_uint32_t *QuantScale){
+    
+  ogg_int16_t UDMod[72];
+  ogg_int16_t LRMod[72];
+  unsigned int j,k,l;
+  const unsigned char * Src;
+  unsigned int QValue = QuantScale[FragQIndex];
+  
+  unsigned char p;
+  unsigned char pl;
+  unsigned char pr;
+  unsigned char pu;
+  unsigned char pd;
+  
+  int  al;
+  int  ar;
+  int  au;
+  int  ad;
+  
+  int  atot;
+  int  B;
+  int  newVal;
+
+  const unsigned char *curRow = SrcPtr - 1; /* avoid negative array indexes */
+  unsigned char *dstRow = DstPtr;
+  const unsigned char *lastRow = SrcPtr-Pitch;
+  const unsigned char *nextRow = SrcPtr+Pitch;
+ 
+  unsigned int rowOffset = 0;
+  unsigned int round = (1<<6);
+  
+  int High;
+  int Low;
+  int TmpMod;
+  
+  int Sharpen = SharpenModifier[FragQIndex];
+  High = 3 * QValue;
+  if(High>32)High=32;
+  Low = 0;
+
+    
+  /* Initialize the Mod Data */
+  Src = SrcPtr-Pitch;
+  for(k=0;k<9;k++){           
+    for(j=0;j<8;j++){
+      
+      TmpMod = 32 + QValue - (abs(Src[j+Pitch]-Src[j]));
+      
+      if(TmpMod< -64)
+	TmpMod = Sharpen;
+      
+      else if(TmpMod<Low)
+	TmpMod = Low;
+      
+      else if(TmpMod>High)
+	TmpMod = High;
+      
+      UDMod[k*8+j] = (ogg_int16_t)TmpMod;
+    }
+    Src +=Pitch;
+  }
+  
+  Src = SrcPtr-1;
+  
+  for(k=0;k<8;k++){           
+    for(j=0;j<9;j++){
+      TmpMod = 32 + QValue - (abs(Src[j+1]-Src[j]));
+      
+      if(TmpMod< -64 )
+	TmpMod = Sharpen;
+      
+      else if(TmpMod<0)
+	TmpMod = Low;
+      
+      else if(TmpMod>High)
+	TmpMod = High;
+      
+      LRMod[k*9+j] = (ogg_int16_t)TmpMod;
+    }
+    Src+=Pitch;
+  }
+  
+  for(k=0;k<8;k++){
+    /* In the case that this function called with same buffer for
+     source and destination, To keep the c and the mmx version to have
+     consistant results, intermediate buffer is used to store the
+     eight pixel value before writing them to destination
+     (i.e. Overwriting souce for the speical case) */
+    for(l=0;l<8;l++){
+    
+      atot = 128;
+      B = round;
+      p = curRow[ rowOffset +l +1];
+      
+      pl = curRow[ rowOffset +l];
+      al = LRMod[k*9+l];
+      atot -= al;
+      B += al * pl; 
+      
+      pu = lastRow[ rowOffset +l];
+      au = UDMod[k*8+l];
+      atot -= au;
+      B += au * pu;
+      
+      pd = nextRow[ rowOffset +l];
+      ad = UDMod[(k+1)*8+l];
+      atot -= ad;
+      B += ad * pd;
+      
+      pr = curRow[ rowOffset +l+2];
+      ar = LRMod[k*9+l+1];
+      atot -= ar;
+      B += ar * pr;
+      
+      newVal = ( atot * p + B) >> 7;
+      
+      dstRow[ rowOffset +l]= clamp255( newVal );
+    }
+    rowOffset += Pitch;
+  }
+}
+
+static void DeringBlockWeak(PB_INSTANCE *pbi, 
+                     unsigned char *SrcPtr,
+                     unsigned char *DstPtr,
+                     ogg_int32_t Pitch,
+                     ogg_uint32_t FragQIndex,
+                     ogg_uint32_t *QuantScale){
+  
+  ogg_int16_t UDMod[72];
+  ogg_int16_t LRMod[72];
+  unsigned int j,k;
+  const unsigned char * Src;
+  unsigned int QValue = QuantScale[FragQIndex];
+  
+  unsigned char p;
+  unsigned char pl;
+  unsigned char pr;
+  unsigned char pu;
+  unsigned char pd;
+  
+  int  al;
+  int  ar;
+  int  au;
+  int  ad;
+  
+  int  atot;
+  int  B;
+  int  newVal;
+  
+  const unsigned char *curRow = SrcPtr-1;
+  unsigned char *dstRow = DstPtr;
+  const unsigned char *lastRow = SrcPtr-Pitch;
+  const unsigned char *nextRow = SrcPtr+Pitch;
+  
+  unsigned int rowOffset = 0;
+  unsigned int round = (1<<6);
+  
+  int High;
+  int Low;
+  int TmpMod;
+  int Sharpen = SharpenModifier[FragQIndex];
+
+  High = 3 * QValue;
+  if(High>24)
+    High=24;
+  Low = 0 ;
+  
+  /* Initialize the Mod Data */
+  Src=SrcPtr-Pitch;
+  for(k=0;k<9;k++) {           
+    for(j=0;j<8;j++) {
+      
+      TmpMod = 32 + QValue - 2*(abs(Src[j+Pitch]-Src[j]));
+
+      if(TmpMod< -64)
+	TmpMod = Sharpen;
+      
+      else if(TmpMod<Low)
+	TmpMod = Low;
+      
+            else if(TmpMod>High)
+	      TmpMod = High;
+      
+      UDMod[k*8+j] = (ogg_int16_t)TmpMod;
+    }
+    Src +=Pitch;
+  }
+  
+  Src = SrcPtr-1;
+
+  for(k=0;k<8;k++){           
+    for(j=0;j<9;j++){
+      TmpMod = 32 + QValue - 2*(abs(Src[j+1]-Src[j]));
+            
+      if(TmpMod< -64 )
+	TmpMod = Sharpen;
+      
+      else if(TmpMod<Low)
+	TmpMod = Low;
+      
+      else if(TmpMod>High)
+	TmpMod = High;
+      
+      LRMod[k*9+j] = (ogg_int16_t)TmpMod;
+    }
+    Src+=Pitch;
+  }
+  
+  for(k=0;k<8;k++) {
+    for(j=0;j<8;j++){
+      atot = 128;
+      B = round;
+      p = curRow[ rowOffset +j+1];
+      
+      pl = curRow[ rowOffset +j];
+      al = LRMod[k*9+j];
+      atot -= al;
+      B += al * pl;
+	
+      pu = lastRow[ rowOffset +j];
+      au = UDMod[k*8+j];
+      atot -= au;
+      B += au * pu;
+	
+      pd = nextRow[ rowOffset +j];
+      ad = UDMod[(k+1)*8+j];
+      atot -= ad;
+      B += ad * pd;
+      
+      pr = curRow[ rowOffset +j+2];
+      ar = LRMod[k*9+j+1];
+      atot -= ar;
+      B += ar * pr;
+      
+      newVal = ( atot * p + B) >> 7;
+      
+      dstRow[ rowOffset +j] = clamp255( newVal );
+    }
+    
+    rowOffset += Pitch;
+  }
+}
+
+static void DeringBlock(const PB_INSTANCE *pbi, 
+                 const unsigned char *SrcPtr,
+                 unsigned char *DstPtr,
+                 const ogg_int32_t Pitch,
+                 ogg_uint32_t FragQIndex,
+                 const ogg_uint32_t *QuantScale,
+                 ogg_uint32_t Variance){
+
+  int N[8]; 
+  unsigned int j,k,l;
+  unsigned int QValue = QuantScale[FragQIndex];
+  
+  int  atot;
+  int  B;
+  int newVal;
+
+  const unsigned char *srcRow = SrcPtr-Pitch-1;
+  unsigned char *dstRow = DstPtr;
+ 
+  unsigned int round = (1<<7);
+  
+  int High;
+  int Low;
+  int TmpMod;
+  int Sharpen = SharpenModifier[FragQIndex];
+  
+  int Slope = 4;
+  
+  if(pbi->PostProcessingLevel > 100)
+    QValue = pbi->PostProcessingLevel - 100;
+
+  if ( Variance > 32768)
+    Slope = 4;
+  else if (Variance > 2048)
+    Slope = 8;
+  
+  High = 3 * QValue;  
+  if(High>32)
+    High=32;
+  Low = 0;
+
+  for(k=0;k<8;k++){
+    /* loop expanded for speed */
+    for(j=0;j<8;j++){
+      /* set up 8 neighbors of pixel srcRow[j] */
+      N[0] = srcRow[j            ]; 
+      N[1] = srcRow[j          +1]; 
+      N[2] = srcRow[j          +2];
+      N[3] = srcRow[j  +Pitch    ];
+      N[4] = srcRow[j  +Pitch  +2];
+      N[5] = srcRow[j +Pitch*2   ];
+      N[6] = srcRow[j +Pitch*2 +1];
+      N[7] = srcRow[j +Pitch*2 +2];
+      
+      // column 0 
+      atot = 256;
+      B = round;
+      
+      for(l = 0; l<8; l++){
+	TmpMod = 32 + QValue - (Slope *(abs(srcRow[j+Pitch+1]-N[l])) >> 2);
+	
+	if(TmpMod< -64)
+	  TmpMod = Sharpen;
+	
+	else if(TmpMod<Low)
+	  TmpMod = Low;
+	
+	else if(TmpMod>High)
+	  TmpMod = High;
+	
+	atot -= TmpMod;
+	B += TmpMod * N[l];
+	
+      }
+      
+      newVal = ( atot * srcRow[j+Pitch+1] + B) >> 8;
+            
+      dstRow[j] = clamp255( newVal );
+    }
+        
+    dstRow += Pitch;
+    srcRow += Pitch;
+  }
+}
+
+static void DeringFrame(PB_INSTANCE *pbi, 
+			unsigned char *Src, unsigned char *Dst){
+  ogg_uint32_t  col,row;
+  unsigned char  *SrcPtr;
+  unsigned char  *DestPtr;
+  ogg_uint32_t BlocksAcross,BlocksDown;
+  ogg_uint32_t *QuantScale;
+  ogg_uint32_t Block;
+  ogg_uint32_t LineLength;
+  
+  ogg_int32_t Thresh1,Thresh2,Thresh3,Thresh4;
+
+  Thresh1 = 384;                  
+  Thresh2 = 4 * Thresh1;          
+  Thresh3 = 5 * Thresh2/4;        
+  Thresh4 = 5 * Thresh2/2;        
+  
+  QuantScale = DeringModifierV1;
+  
+  BlocksAcross = pbi->HFragments;
+  BlocksDown = pbi->VFragments;
+  
+  SrcPtr = Src + pbi->ReconYDataOffset;
+  DestPtr = Dst + pbi->ReconYDataOffset;
+  LineLength = pbi->Configuration.YStride;
+  
+  Block = 0;
+  
+  for ( row = 0 ; row < BlocksDown; row ++){
+    for (col = 0; col < BlocksAcross; col ++){
+      ogg_uint32_t Quality = pbi->FragQIndex[Block]; 
+      ogg_int32_t Variance = pbi->FragmentVariances[Block]; 
+      
+      if( pbi->PostProcessingLevel >5 && Variance > Thresh3 ){
+	DeringBlockStrong(pbi, SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+				
+	if( (col > 0 && 
+	     pbi->FragmentVariances[Block-1] > Thresh4 ) ||
+	    (col + 1 < BlocksAcross && 
+	     pbi->FragmentVariances[Block+1] > Thresh4 ) ||
+	    (row + 1 < BlocksDown && 
+	     pbi->FragmentVariances[Block+BlocksAcross] > Thresh4) ||
+	    (row > 0 && 
+	     pbi->FragmentVariances[Block-BlocksAcross] > Thresh4) ){
+
+	  DeringBlockStrong(pbi, SrcPtr + 8 * col, DestPtr + 8 * col, 
+			    LineLength,Quality,QuantScale);
+	  DeringBlockStrong(pbi, SrcPtr + 8 * col, DestPtr + 8 * col, 
+			    LineLength,Quality,QuantScale);
+	}			
+      } else if(Variance > Thresh2 ) {
+	
+	DeringBlockStrong(pbi, SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+      } else if(Variance > Thresh1 ) {
+
+	DeringBlockWeak(pbi, SrcPtr + 8 * col, DestPtr + 8 * col, 
+			LineLength,Quality,QuantScale);
+      
+      } else {
+
+	CopyBlock(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
+
+      }
+			
+      ++Block;
+      
+    }
+    SrcPtr += 8 * LineLength;
+    DestPtr += 8 * LineLength;
+  }
+
+  /* Then U */
+
+  BlocksAcross /= 2;
+  BlocksDown /= 2;
+  LineLength /= 2;
+  
+  SrcPtr = Src + pbi->ReconUDataOffset;
+  DestPtr = Dst + pbi->ReconUDataOffset;
+  for ( row = 0 ; row < BlocksDown; row ++) {
+    for (col = 0; col < BlocksAcross; col ++) {
+      ogg_uint32_t Quality = pbi->FragQIndex[Block]; 
+      ogg_int32_t Variance = pbi->FragmentVariances[Block]; 
+			
+      if( pbi->PostProcessingLevel >5 && Variance > Thresh4 ) {
+	DeringBlockStrong(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+	DeringBlockStrong(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+	DeringBlockStrong(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+	
+      }else if(Variance > Thresh2 ){
+	DeringBlockStrong(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+      }else if(Variance > Thresh1 ){
+	DeringBlockWeak(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			LineLength,Quality,QuantScale);
+      }else{
+	CopyBlock(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
+      }
+      
+      ++Block;
+      
+    }
+    SrcPtr += 8 * LineLength;
+    DestPtr += 8 * LineLength;
+  }
+  
+  /* Then V */
+  SrcPtr = Src + pbi->ReconVDataOffset;
+  DestPtr = Dst + pbi->ReconVDataOffset;
+  
+  for ( row = 0 ; row < BlocksDown; row ++){
+    for (col = 0; col < BlocksAcross; col ++){
+      
+      ogg_uint32_t Quality = pbi->FragQIndex[Block]; 
+      ogg_int32_t Variance = pbi->FragmentVariances[Block]; 
+      
+			
+      if( pbi->PostProcessingLevel >5 && Variance > Thresh4 ) {
+	DeringBlockStrong(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+	DeringBlockStrong(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+	DeringBlockStrong(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+				
+      }else if(Variance > Thresh2 ){
+	DeringBlockStrong(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			  LineLength,Quality,QuantScale);
+      }else if(Variance > Thresh1 ){
+	DeringBlockWeak(pbi,SrcPtr + 8 * col, DestPtr + 8 * col, 
+			LineLength,Quality,QuantScale);
+      }else{
+	CopyBlock(SrcPtr + 8 * col, DestPtr + 8 * col, LineLength);
+      }
+      
+      ++Block;
+      
+    }
+    SrcPtr += 8 * LineLength;
+    DestPtr += 8 * LineLength;
+    
+  }
+  
+}
+
+static void UpdateFragQIndex(PB_INSTANCE *pbi){
+  
+  ogg_uint32_t  ThisFrameQIndex;
+  ogg_uint32_t  i;
+
+  /* Check this frame quality  index */
+  ThisFrameQIndex = pbi->FrameQIndex;
+  
+  
+  /* It is not a key frame, so only reset those are coded */
+  for( i = 0; i < pbi->UnitFragments; i++  )
+    if( pbi->display_fragments[i])
+      pbi->FragQIndex[i] = ThisFrameQIndex;
+  
+}
+
+static void DeblockLoopFilteredBand(PB_INSTANCE *pbi, 
+			     unsigned char *SrcPtr, 
+			     unsigned char *DesPtr,
+			     ogg_uint32_t PlaneLineStep, 
+			     ogg_uint32_t FragsAcross,
+			     ogg_uint32_t StartFrag,
+			     ogg_uint32_t *QuantScale){
+  ogg_uint32_t j,k;
+  ogg_uint32_t CurrentFrag=StartFrag;
+  ogg_int32_t QStep;
+  ogg_int32_t FLimit;
+  unsigned char *Src, *Des;
+  ogg_int32_t  x[10];
+  ogg_int32_t  Sum1, Sum2;
+  
+  while(CurrentFrag < StartFrag + FragsAcross){
+    
+    Src=SrcPtr+8*(CurrentFrag-StartFrag)-PlaneLineStep*5;
+    Des=DesPtr+8*(CurrentFrag-StartFrag)-PlaneLineStep*4;
+    
+    QStep = QuantScale[pbi->FragQIndex[CurrentFrag+FragsAcross]];
+    FLimit = ( QStep * 3 ) >> 2;
+    
+    for( j=0; j<8 ; j++){
+      x[0] = Src[0];
+      x[1] = Src[PlaneLineStep];
+      x[2] = Src[PlaneLineStep*2];
+      x[3] = Src[PlaneLineStep*3];
+      x[4] = Src[PlaneLineStep*4];
+      x[5] = Src[PlaneLineStep*5];
+      x[6] = Src[PlaneLineStep*6];
+      x[7] = Src[PlaneLineStep*7];
+      x[8] = Src[PlaneLineStep*8];
+      x[9] = Src[PlaneLineStep*9];
+
+      Sum1=Sum2=0;
+      
+      for(k=1;k<=4;k++){   
+	Sum1 += abs(x[k]-x[k-1]);
+	Sum2 += abs(x[k+4]-x[k+5]);           
+      }
+      
+      pbi->FragmentVariances[CurrentFrag] +=((Sum1>255)?255:Sum1);
+      pbi->FragmentVariances[CurrentFrag + FragsAcross] += ((Sum2>255)?255:Sum2);
+      
+      if( Sum1 < FLimit &&
+	  Sum2 < FLimit &&
+	  (x[5] - x[4]) < QStep && 
+	  (x[4] - x[5]) < QStep ){
+	
+	/* low pass filtering (LPF7: 1 1 1 2 1 1 1) */
+	Des[0              ] = (x[0] + x[0] +x[0] + x[1] * 2 + 
+				x[2] + x[3] +x[4] + 4) >> 3;
+	Des[PlaneLineStep  ] = (x[0] + x[0] +x[1] + x[2] * 2 + 
+				x[3] + x[4] +x[5] + 4) >> 3;
+	Des[PlaneLineStep*2] = (x[0] + x[1] +x[2] + x[3] * 2 + 
+				x[4] + x[5] +x[6] + 4) >> 3;
+	Des[PlaneLineStep*3] = (x[1] + x[2] +x[3] + x[4] * 2 + 
+				x[5] + x[6] +x[7] + 4) >> 3;
+	Des[PlaneLineStep*4] = (x[2] + x[3] +x[4] + x[5] * 2 + 
+				x[6] + x[7] +x[8] + 4) >> 3;
+	Des[PlaneLineStep*5] = (x[3] + x[4] +x[5] + x[6] * 2 + 
+				x[7] + x[8] +x[9] + 4) >> 3;
+	Des[PlaneLineStep*6] = (x[4] + x[5] +x[6] + x[7] * 2 + 
+				x[8] + x[9] +x[9] + 4) >> 3;
+	Des[PlaneLineStep*7] = (x[5] + x[6] +x[7] + x[8] * 2 + 
+				x[9] + x[9] +x[9] + 4) >> 3;
+	
+      }else {
+	/* copy the pixels to destination */
+	Des[0              ]= x[1];
+	Des[PlaneLineStep  ]= x[2];
+	Des[PlaneLineStep*2]= x[3];
+	Des[PlaneLineStep*3]= x[4];
+	Des[PlaneLineStep*4]= x[5];
+	Des[PlaneLineStep*5]= x[6];
+	Des[PlaneLineStep*6]= x[7];
+	Des[PlaneLineStep*7]= x[8];
+      }
+      Src ++;
+      Des ++;             
+    }
+    
+  }
+
+  /* done with filtering the horizontal edge, now let's do the
+     vertical one */
+  /* skip the first one */
+  if(CurrentFrag==StartFrag)
+    CurrentFrag++;
+  else{
+    Des=DesPtr-8*PlaneLineStep+8*(CurrentFrag-StartFrag);
+    Src=Des-5;
+    Des-=4;
+
+    QStep = QuantScale[pbi->FragQIndex[CurrentFrag]];
+    FLimit = ( QStep * 3 ) >> 2;
+    
+    for( j=0; j<8 ; j++){
+      x[0] = Src[0];
+      x[1] = Src[1];
+      x[2] = Src[2];
+      x[3] = Src[3];
+      x[4] = Src[4];
+      x[5] = Src[5];
+      x[6] = Src[6];
+      x[7] = Src[7];
+      x[8] = Src[8];
+      x[9] = Src[9];
+                
+      Sum1=Sum2=0;
+      
+      for(k=1;k<=4;k++){   
+	Sum1 += abs(x[k]-x[k-1]);
+	Sum2 += abs(x[k+4]-x[k+5]);           
+      }
+
+      pbi->FragmentVariances[CurrentFrag-1] += ((Sum1>255)?255:Sum1);
+      pbi->FragmentVariances[CurrentFrag] += ((Sum2>255)?255:Sum2);
+      
+      if( Sum1 < FLimit &&
+	  Sum2 < FLimit &&
+	  (x[5] - x[4]) < QStep && 
+	  (x[4] - x[5]) < QStep ){
+	
+	/* low pass filtering (LPF7: 1 1 1 2 1 1 1) */
+	Des[0] = (x[0] + x[0] +x[0] + x[1] * 2 + x[2] + x[3] +x[4] + 4) >> 3;
+	Des[1] = (x[0] + x[0] +x[1] + x[2] * 2 + x[3] + x[4] +x[5] + 4) >> 3;
+	Des[2] = (x[0] + x[1] +x[2] + x[3] * 2 + x[4] + x[5] +x[6] + 4) >> 3;
+	Des[3] = (x[1] + x[2] +x[3] + x[4] * 2 + x[5] + x[6] +x[7] + 4) >> 3;
+	Des[4] = (x[2] + x[3] +x[4] + x[5] * 2 + x[6] + x[7] +x[8] + 4) >> 3;
+	Des[5] = (x[3] + x[4] +x[5] + x[6] * 2 + x[7] + x[8] +x[9] + 4) >> 3;
+	Des[6] = (x[4] + x[5] +x[6] + x[7] * 2 + x[8] + x[9] +x[9] + 4) >> 3;
+	Des[7] = (x[5] + x[6] +x[7] + x[8] * 2 + x[9] + x[9] +x[9] + 4) >> 3;
+      }
+      
+      Src += PlaneLineStep;
+      Des += PlaneLineStep;               
+    }
+    CurrentFrag ++;
+  }
+}
+
+static void DeblockVerticalEdgesInLoopFilteredBand(PB_INSTANCE *pbi, 
+					    unsigned char *SrcPtr, 
+					    unsigned char *DesPtr, 
+					    ogg_uint32_t PlaneLineStep,
+					    ogg_uint32_t FragsAcross,
+					    ogg_uint32_t StartFrag,
+					    ogg_uint32_t *QuantScale){
+  ogg_uint32_t j,k;
+  ogg_uint32_t CurrentFrag=StartFrag;
+  ogg_int32_t QStep;
+  ogg_int32_t FLimit;
+  unsigned char *Src, *Des;
+  ogg_int32_t  x[10];
+  ogg_int32_t  Sum1, Sum2;
+    
+  while(CurrentFrag < StartFrag + FragsAcross-1) {
+    
+    Src=SrcPtr+8*(CurrentFrag-StartFrag+1)-5;
+    Des=DesPtr+8*(CurrentFrag-StartFrag+1)-4;
+    
+    QStep = QuantScale[pbi->FragQIndex[CurrentFrag+1]];
+    FLimit = ( QStep * 3)>>2 ;        
+    
+    for( j=0; j<8 ; j++){                
+      x[0] = Src[0];
+      x[1] = Src[1];
+      x[2] = Src[2];
+      x[3] = Src[3];
+      x[4] = Src[4];
+      x[5] = Src[5];
+      x[6] = Src[6];
+      x[7] = Src[7];
+      x[8] = Src[8];
+      x[9] = Src[9];
+                
+      Sum1=Sum2=0;
+      
+      for(k=1;k<=4;k++){   
+	Sum1 += abs(x[k]-x[k-1]);
+	Sum2 += abs(x[k+4]-x[k+5]);           
+      }
+      
+      pbi->FragmentVariances[CurrentFrag] += ((Sum1>255)?255:Sum1);
+      pbi->FragmentVariances[CurrentFrag+1] += ((Sum2>255)?255:Sum2);
+      
+                               
+      if( Sum1 < FLimit &&
+	  Sum2 < FLimit &&
+	  (x[5] - x[4]) < QStep && 
+	  (x[4] - x[5]) < QStep ){
+	
+	/* low pass filtering (LPF7: 1 1 1 2 1 1 1) */
+	Des[0] = (x[0] + x[0] +x[0] + x[1] * 2 + x[2] + x[3] +x[4] + 4) >> 3;
+	Des[1] = (x[0] + x[0] +x[1] + x[2] * 2 + x[3] + x[4] +x[5] + 4) >> 3;
+	Des[2] = (x[0] + x[1] +x[2] + x[3] * 2 + x[4] + x[5] +x[6] + 4) >> 3;
+	Des[3] = (x[1] + x[2] +x[3] + x[4] * 2 + x[5] + x[6] +x[7] + 4) >> 3;
+	Des[4] = (x[2] + x[3] +x[4] + x[5] * 2 + x[6] + x[7] +x[8] + 4) >> 3;
+	Des[5] = (x[3] + x[4] +x[5] + x[6] * 2 + x[7] + x[8] +x[9] + 4) >> 3;
+	Des[6] = (x[4] + x[5] +x[6] + x[7] * 2 + x[8] + x[9] +x[9] + 4) >> 3;
+	Des[7] = (x[5] + x[6] +x[7] + x[8] * 2 + x[9] + x[9] +x[9] + 4) >> 3;
+      }
+      Src +=PlaneLineStep;
+                Des +=PlaneLineStep;                
+
+    }     
+    CurrentFrag ++;
+  } 
+}
+
+static void DeblockPlane(PB_INSTANCE *pbi, 
+		  unsigned char *SourceBuffer, 
+		  unsigned char *DestinationBuffer, 
+		  ogg_uint32_t Channel ){
+  
+  ogg_uint32_t i,k;
+  ogg_uint32_t PlaneLineStep=0;
+  ogg_uint32_t StartFrag =0;
+  ogg_uint32_t PixelIndex=0;
+  unsigned char * SrcPtr=0, * DesPtr=0;
+  ogg_uint32_t FragsAcross=0;
+  ogg_uint32_t FragsDown=0;
+  ogg_uint32_t *QuantScale=0;
+  
+  switch( Channel ){    
+  case 0:
+    /* Get the parameters */
+    PlaneLineStep = pbi->Configuration.YStride; 
+    FragsAcross = pbi->HFragments;
+    FragsDown = pbi->VFragments;
+    StartFrag = 0;
+    PixelIndex = pbi->ReconYDataOffset;
+    SrcPtr = & SourceBuffer[PixelIndex];
+    DesPtr = & DestinationBuffer[PixelIndex];
+    break;
+    
+  case 1:
+    /* Get the parameters */
+    PlaneLineStep = pbi->Configuration.UVStride;    
+    FragsAcross = pbi->HFragments / 2;
+    FragsDown = pbi->VFragments / 2;
+    StartFrag = pbi->YPlaneFragments;
+    
+    PixelIndex = pbi->ReconUDataOffset;
+    SrcPtr = & SourceBuffer[PixelIndex];
+    DesPtr = & DestinationBuffer[PixelIndex];
+    break;
+
+  default:
+    /* Get the parameters */
+    PlaneLineStep = pbi->Configuration.UVStride;    
+    FragsAcross = pbi->HFragments / 2;
+    FragsDown = pbi->VFragments / 2;
+    StartFrag =   pbi->YPlaneFragments + pbi->UVPlaneFragments;
+	
+    PixelIndex = pbi->ReconVDataOffset;
+    SrcPtr = & SourceBuffer[PixelIndex];
+    DesPtr = & DestinationBuffer[PixelIndex];
+    break;
+  }
+  
+  QuantScale = DcQuantScaleV1;
+    
+  for(i=0;i<4;i++)
+    memcpy(DesPtr+i*PlaneLineStep, SrcPtr+i*PlaneLineStep, PlaneLineStep);
+
+  k = 1;
+
+  while( k < FragsDown ){
+
+    SrcPtr += 8*PlaneLineStep;
+    DesPtr += 8*PlaneLineStep;
+    
+    /* Filter both the horizontal and vertical block edges inside the band */
+    DeblockLoopFilteredBand(pbi, SrcPtr, DesPtr, PlaneLineStep, 
+			    FragsAcross, StartFrag, QuantScale);
+    
+    /* Move Pointers */
+    StartFrag += FragsAcross;
+    
+    k ++;   
+  }
+
+  /* The Last band */
+  for(i=0;i<4;i++)
+    memcpy(DesPtr+(i+4)*PlaneLineStep, 
+	   SrcPtr+(i+4)*PlaneLineStep, 
+	   PlaneLineStep);
+  
+  DeblockVerticalEdgesInLoopFilteredBand(pbi,SrcPtr,DesPtr,PlaneLineStep, 
+					 FragsAcross,StartFrag,QuantScale);
+  
+}
+
+static void DeblockFrame(PB_INSTANCE *pbi, unsigned char *SourceBuffer, 
+		  unsigned char *DestinationBuffer){ 
+
+  memset(pbi->FragmentVariances, 0 , sizeof(ogg_int32_t) * pbi->UnitFragments);
+  
+  
+  UpdateFragQIndex(pbi);
+
+  
+  SetupLoopFilter(pbi);
+  
+  /* Y */
+  DeblockPlane( pbi, SourceBuffer, DestinationBuffer, 0);
+        
+  /* U */
+  DeblockPlane( pbi, SourceBuffer, DestinationBuffer, 1);
+        
+  /* V */
+  DeblockPlane( pbi, SourceBuffer, DestinationBuffer, 2);
+  
+}
+
+void PostProcess(PB_INSTANCE *pbi){
+
+  switch (pbi->PostProcessingLevel){
+  case 8:
+    /* on a slow machine, use a simpler and faster deblocking filter */
+    DeblockFrame(pbi, pbi->LastFrameRecon,pbi->PostProcessBuffer);
+    break;
+    
+  case 6:
+    DeblockFrame(pbi, pbi->LastFrameRecon,pbi->PostProcessBuffer);
+    UpdateUMVBorder(pbi, pbi->PostProcessBuffer );
+    DeringFrame(pbi, pbi->PostProcessBuffer, pbi->PostProcessBuffer);
+    break;
+    
+  case 5:
+    DeblockFrame(pbi, pbi->LastFrameRecon,pbi->PostProcessBuffer);
+    UpdateUMVBorder(pbi, pbi->PostProcessBuffer );
+    DeringFrame(pbi, pbi->PostProcessBuffer, pbi->PostProcessBuffer);
+    break;
+  case 4:
+    DeblockFrame(pbi, pbi->LastFrameRecon, pbi->PostProcessBuffer);
+    break;
+  case 1:
+    UpdateFragQIndex(pbi);
+    break;
+    
+  case 0:
+    break;
+    
+  default:
+    DeblockFrame(pbi, pbi->LastFrameRecon, pbi->PostProcessBuffer);
+    UpdateUMVBorder(pbi, pbi->PostProcessBuffer );
+    DeringFrame(pbi, pbi->PostProcessBuffer, pbi->PostProcessBuffer);
+    break;
+  }
+}
+

<p><p>1.4       +15 -15    theora/lib/toplevel.c

Index: toplevel.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/toplevel.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- toplevel.c	18 Sep 2002 08:56:57 -0000	1.3
+++ toplevel.c	20 Sep 2002 09:30:32 -0000	1.4
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: toplevel.c,v 1.3 2002/09/18 08:56:57 xiphmont Exp $
+  last mod: $Id: toplevel.c,v 1.4 2002/09/20 09:30:32 xiphmont Exp $
 
  ********************************************************************/
 
@@ -19,7 +19,7 @@
 #include <ogg/ogg.h>
 #include <theora/theora.h>
 #include "encoder_internal.h"
-#include "encoder_lookup.h"
+#include "toplevel_lookup.h"
 
 #define A_TABLE_SIZE	    29
 #define DF_CANDIDATE_WINDOW 5
@@ -79,14 +79,14 @@
   cpi->BlockCodedFlags = 0;
 }
 
-static void EAllocateFragmentInfo(CP_INSTANCE * cpi){
+static void EInitFragmentInfo(CP_INSTANCE * cpi){
   
   /* clear any existing info */
-  EDeleteFragmentInfo(cpi);
+  EClearFragmentInfo(cpi);
   
   /* Perform Fragment Allocations */
   cpi->extra_fragments =  
-    _ogg_malloc(32+cpi->pb.UnitFragments*sizeof(unsigned char));
+    _ogg_malloc(cpi->pb.UnitFragments*sizeof(unsigned char));
   
   /* A note to people reading and wondering why malloc returns aren't
      checked:
@@ -188,11 +188,11 @@
   
 }
 
-void EateFrameInfo(CP_INSTANCE * cpi){
+void EInitFrameInfo(CP_INSTANCE * cpi){
   int FrameSize = cpi->pb.ReconYPlaneSize + 2 * cpi->pb.ReconUVPlaneSize;
 
   /* clear any existing info */
-  EDeleteFrameInfo(cpi);
+  EClearFrameInfo(cpi);
 
   /* allocate frames */
   cpi->ConvDestBuffer = 
@@ -660,7 +660,7 @@
     
     
     /* Set Baseline filter level. */
-    SetScanParam( &cpi->pp, SCP_CONFIGURE_PP, cpi->PreProcFilterLevel );
+    ConfigurePP( &cpi->pp, cpi->PreProcFilterLevel );
     
     /* Score / analyses the fragments. */ 
     cpi->MotionScore = YUVAnalyseFrame(&cpi->pp, &KFIndicator );
@@ -800,8 +800,8 @@
   c->version_minor=VERSION_MINOR;
   c->version_subminor=VERSION_SUB;
 
-  AllocateTmpBuffers(&cpi->pb);
-  CreatePPInstance(&cpi->pp);
+  InitTmpBuffers(&cpi->pb);
+  InitPPInstance(&cpi->pp);
 
   /* Initialise Configuration structure to legal values */
   cpi->Configuration.BaseQ = 32;
@@ -882,8 +882,8 @@
   
   /* Initialise image format details */
   InitFrameDetails(&cpi->pb);
-  EAllocateFragmentInfo(cpi);
-  EAllocateFrameInfo(cpi);
+  EInitFragmentInfo(cpi);
+  EInitFrameInfo(cpi);
 
   /* Set up pre-processor config pointers. */
   cpi->ScanConfig.Yuv0ptr = cpi->yuv0ptr;
@@ -940,8 +940,7 @@
   cpi->ResidueLastEndSB = 0;  /* Where we were in the residue update
                                  loop last time. */
   
-  /* Select the appropriate huffman set. */
-  SelectHuffmanSet(&cpi->pb);
+  InitHuffmanSet(&cpi->pb);
 
   /* This makes sure encoder version specific tables are initialised */
   InitQTables(&cpi->pb);  
@@ -1086,10 +1085,11 @@
 void theora_encode_clear(CP_INSTANCE *cpi){
   if(cpi){
     
+    ClearHuffmanSet(&cpi->pb);
     ClearFragmentInfo(&cpi->pb);
     ClearFrameInfo(&cpi->pb);
     EClearFragmentInfo(cpi);
-    ECleadFrameInfo(cpi);		
+    EClearFrameInfo(cpi);		
     ClearTmpBuffers(&cpi->pb);
     ClearPPInstance(&cpi->pp);
     

<p><p>1.1                  theora/lib/block_inline.h

Index: block_inline.h
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: block_inline.h,v 1.1 2002/09/20 09:30:31 xiphmont Exp $

 ********************************************************************/

tatic ogg_int32_t MBOrderMap[4] = { 0, 2, 3, 1 };
static ogg_int32_t BlockOrderMap1[4][4] =	
{ { 0, 1, 3, 2 },
  { 0, 2, 3, 1 },       
  { 0, 2, 3, 1 },
  { 3, 2, 0, 1 }
};

tatic ogg_int32_t BlockOrderMap2[4][4] =	
{ { 0, 1, 2, 3 },
  { 0, 1, 2, 3 },       
  { 0, 1, 2, 3 },
  { 0, 1, 2, 3 }
};
       
/* The following hard wired tables and masks are used to decode block
   pattern tokens */
static unsigned char BlockPatternMask[4] = { 
  0x08, 0x04, 0x02, 0x01 };

tatic unsigned char BlockDecode1[2][8] = {	
  { 0x01, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 },
  { 0x07, 0x0B, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00 } };

tatic unsigned char BlockDecode2[2][16] = {	
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 
    0x0A, 0x03, 0x0E, 0x07, 0x0D, 0x05, 0x0C, 0x02 },  
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
    0x05, 0x03, 0x02, 0x0C, 0x04, 0x0A, 0x08, 0x0D } };

tatic unsigned char BlockDecode3[2][32] = {	
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x09, 0x06, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } };

tatic ogg_uint32_t BPPredictor[15] = { 
  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1  };	

         
static ogg_int32_t QuadMapToIndex1( ogg_int32_t	(*BlockMap)[4][4], 
                                    ogg_uint32_t SB, ogg_uint32_t MB, 
                                    ogg_uint32_t B ){
  return BlockMap[SB][MBOrderMap[MB]][BlockOrderMap1[MB][B]];
}

tatic ogg_int32_t QuadMapToIndex2( ogg_int32_t	(*BlockMap)[4][4], 
                                    ogg_uint32_t SB, ogg_uint32_t MB, 
                                    ogg_uint32_t B ){
  return BlockMap[SB][MBOrderMap[MB]][BlockOrderMap2[MB][B]];
}

tatic ogg_int32_t QuadMapToMBTopLeft( ogg_int32_t (*BlockMap)[4][4], 
                                       ogg_uint32_t SB, ogg_uint32_t MB ){
  return BlockMap[SB][MBOrderMap[MB]][0];
}

<p><p><p>1.1                  theora/lib/blockmap.c

Index: blockmap.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: blockmap.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <ogg/ogg.h>

void CreateMapping ( ogg_int32_t (*BlockMap)[4][4], ogg_uint32_t FirstSB, 
                     ogg_uint32_t FirstFrag, ogg_uint32_t HFrags, 
                     ogg_uint32_t VFrags ){
  ogg_uint32_t i, j;
  ogg_uint32_t xpos;
  ogg_uint32_t ypos;
  ogg_uint32_t SBrow, SBcol;
  ogg_uint32_t SBRows, SBCols;
  ogg_uint32_t MB, B;	
  
  ogg_uint32_t SB=FirstSB;
  ogg_uint32_t FragIndex=FirstFrag;
  
  /* Set Super-Block dimensions */
  SBRows = VFrags/4 + ( VFrags%4 ? 1 : 0 );
  SBCols = HFrags/4 + ( HFrags%4 ? 1 : 0 );
  
  /* Map each Super-Block */
  for ( SBrow=0; SBrow<SBRows; SBrow++ ){
    for ( SBcol=0; SBcol<SBCols; SBcol++ ){
      /* Y co-ordinate of Super-Block in Block units */
      ypos = SBrow<<2;
      
      /* Map Blocks within this Super-Block */
      for ( i=0; (i<4) && (ypos<VFrags); i++, ypos++ ){
        /* X co-ordinate of Super-Block in Block units */
        xpos = SBcol<<2;
                                
        for ( j=0; (j<4) && (xpos<HFrags); j++, xpos++ ){
          if ( i<2 ){
            MB = ( j<2 ? 0 : 1 );
          }else{
            MB = ( j<2 ? 2 : 3 );
          }
          
          if ( i%2 ){
            B = ( j%2 ? 3 : 2 );
          }else{
            B = ( j%2 ? 1 : 0 );
          }
          
          /* Set mapping and move to next fragment */
          BlockMap[SB][MB][B] = FragIndex++;
        }

        /* Move to first fragment in next row in Super-Block */
        FragIndex += HFrags-j;
      }
      
      /* Move on to next Super-Block */
      SB++;
      FragIndex -= i*HFrags-j;
    }
    
    /* Move to first Super-Block in next row */
    FragIndex += 3*HFrags;
  }
}

void CreateBlockMapping ( ogg_int32_t  (*BlockMap)[4][4], 
                          ogg_uint32_t YSuperBlocks, 
                          ogg_uint32_t UVSuperBlocks, 
                          ogg_uint32_t HFrags, ogg_uint32_t VFrags ) {
  ogg_uint32_t i, j;
  
  for ( i=0; i<YSuperBlocks + UVSuperBlocks * 2; i++ ){
    for ( j=0; j<4; j++ ) {
      BlockMap[i][j][0] = -1;
      BlockMap[i][j][1] = -1;
      BlockMap[i][j][2] = -1;
      BlockMap[i][j][3] = -1;
    }
  }
  
  CreateMapping ( BlockMap, 0, 0, HFrags, VFrags );
  CreateMapping ( BlockMap, YSuperBlocks, HFrags*VFrags, HFrags/2, VFrags/2 );
  CreateMapping ( BlockMap, YSuperBlocks + UVSuperBlocks, (HFrags*VFrags*5)/4,
                  HFrags/2, VFrags/2 );
}

<p><p><p>1.1                  theora/lib/dct.c

Index: dct.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: dct.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <ogg/ogg.h>

#define PI 3.1415926535897
static ogg_int32_t xC1S7 = 64277;
static ogg_int32_t xC2S6 = 60547;
static ogg_int32_t xC3S5 = 54491;
static ogg_int32_t xC4S4 = 46341;
static ogg_int32_t xC5S3 = 36410;
static ogg_int32_t xC6S2 = 25080;
static ogg_int32_t xC7S1 = 12785;

tatic ogg_int32_t xSUM17=77062;
static ogg_int32_t xDIF17=51492;
static ogg_int32_t xSUM35=90901;
static ogg_int32_t xDIF35=18081;
static ogg_int32_t xSUM26=85637;
static ogg_int32_t xDIF26=35467;

#define SIGNBITDUPPED(X) ((signed )(((X) & 0x80000000)) >> 31)
#define DOROUND(X) ( (SIGNBITDUPPED(X) & (0xffff)) + (X) )

void fdct_short ( ogg_int16_t * InputData, ogg_int16_t * OutputData ){
  int loop;
  
  ogg_int32_t  is07, is12, is34, is56;
  ogg_int32_t  is0734, is1256;
  ogg_int32_t  id07, id12, id34, id56; 
  
  ogg_int32_t  irot_input_x, irot_input_y;
  ogg_int32_t  icommon_product1;   /* Re-used product  (c4s4 * (s12 - s56)). */
  ogg_int32_t  icommon_product2;   /* Re-used product  (c4s4 * (d12 + d56)). */
  
  ogg_int32_t  temp1, temp2;	     /* intermediate variable for computation */
  
  ogg_int32_t  InterData[64];
  ogg_int32_t *ip = InterData;
  ogg_int16_t * op = OutputData;
  for (loop = 0; loop < 8; loop++){
    /* Pre calculate some common sums and differences. */
    is07 = InputData[0] + InputData[7];
    is12 = InputData[1] + InputData[2];
    is34 = InputData[3] + InputData[4];
    is56 = InputData[5] + InputData[6];
    
    id07 = InputData[0] - InputData[7];
    id12 = InputData[1] - InputData[2];
    id34 = InputData[3] - InputData[4];
    id56 = InputData[5] - InputData[6];
    
    is0734 = is07 + is34;
    is1256 = is12 + is56;
    
    /* Pre-Calculate some common product terms. */
    icommon_product1 = xC4S4*(is12 - is56); 
    icommon_product1 = DOROUND(icommon_product1);
    icommon_product1>>=16;
    
    icommon_product2 = xC4S4*(id12 + id56);
    icommon_product2 = DOROUND(icommon_product2);
    icommon_product2>>=16;
    
    
    ip[0] = (xC4S4*(is0734 + is1256));
    ip[0] = DOROUND(ip[0]);
    ip[0] >>= 16;
    
    ip[4] = (xC4S4*(is0734 - is1256));
    ip[4] = DOROUND(ip[4]);
    ip[4] >>= 16;
    
    /* Define inputs to rotation for outputs 2 and 6 */
    irot_input_x = id12 - id56;
    irot_input_y = is07 - is34;
    
    /* Apply rotation for outputs 2 and 6.  */
    temp1=xC6S2*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC2S6*irot_input_y;
    temp2=DOROUND(temp2);
    temp2>>=16;
    ip[2] = temp1 + temp2;
    
    temp1=xC6S2*irot_input_y;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC2S6*irot_input_x ;
    temp2=DOROUND(temp2);
    temp2>>=16;
    ip[6] = temp1 -temp2 ;

    /* Define inputs to rotation for outputs 1 and 7  */
    irot_input_x = icommon_product1 + id07;
    irot_input_y = -( id34 + icommon_product2 );
    
    /* Apply rotation for outputs 1 and 7.  */
    
    temp1=xC1S7*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC7S1*irot_input_y;
    temp2=DOROUND(temp2);
    temp2>>=16;
    ip[1] = temp1 - temp2;
    
    temp1=xC7S1*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC1S7*irot_input_y ;
    temp2=DOROUND(temp2);
    temp2>>=16;
    ip[7] = temp1 + temp2 ;
    
    /* Define inputs to rotation for outputs 3 and 5 */
    irot_input_x = id07 - icommon_product1;
    irot_input_y = id34 - icommon_product2;
    
    /* Apply rotation for outputs 3 and 5. */
    temp1=xC3S5*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC5S3*irot_input_y ;
    temp2=DOROUND(temp2);
    temp2>>=16;
    ip[3] = temp1 - temp2 ;

    temp1=xC5S3*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC3S5*irot_input_y;
    temp2=DOROUND(temp2);
    temp2>>=16;
    ip[5] = temp1 + temp2;
    
    /* Increment data pointer for next row. */
    InputData += 8 ;
    ip += 8; /* advance pointer to next row */
                
  }

<p>  /* Performed DCT on rows, now transform the columns */
  ip = InterData;
  for (loop = 0; loop < 8; loop++){
    /* Pre calculate some common sums and differences.  */
    is07 = ip[0 * 8] + ip[7 * 8];
    is12 = ip[1 * 8] + ip[2 * 8];
    is34 = ip[3 * 8] + ip[4 * 8];
    is56 = ip[5 * 8] + ip[6 * 8];
    
    id07 = ip[0 * 8] - ip[7 * 8];
    id12 = ip[1 * 8] - ip[2 * 8];
    id34 = ip[3 * 8] - ip[4 * 8];
    id56 = ip[5 * 8] - ip[6 * 8];
    
    is0734 = is07 + is34;
    is1256 = is12 + is56;
    
    /* Pre-Calculate some common product terms. */
    icommon_product1 = xC4S4*(is12 - is56) ; 
    icommon_product2 = xC4S4*(id12 + id56) ;
    icommon_product1 = DOROUND(icommon_product1);
    icommon_product2 = DOROUND(icommon_product2);
    icommon_product1>>=16;
    icommon_product2>>=16;
    
    
    temp1 = xC4S4*(is0734 + is1256) ;
    temp2 = xC4S4*(is0734 - is1256) ;
    temp1 = DOROUND(temp1);
    temp2 = DOROUND(temp2);
    temp1>>=16;
    temp2>>=16;
    op[0*8] = (ogg_int16_t) temp1;
    op[4*8] = (ogg_int16_t) temp2;
    
    /* Define inputs to rotation for outputs 2 and 6 */
    irot_input_x = id12 - id56;
    irot_input_y = is07 - is34;
    
    /* Apply rotation for outputs 2 and 6.  */
    temp1=xC6S2*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC2S6*irot_input_y;
    temp2=DOROUND(temp2);
    temp2>>=16;
    op[2*8] = (ogg_int16_t) (temp1 + temp2);
    
    temp1=xC6S2*irot_input_y;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC2S6*irot_input_x ;
    temp2=DOROUND(temp2);
    temp2>>=16;
    op[6*8] = (ogg_int16_t) (temp1 -temp2) ;
    
    /* Define inputs to rotation for outputs 1 and 7 */
    irot_input_x = icommon_product1 + id07;
    irot_input_y = -( id34 + icommon_product2 );
    
    /* Apply rotation for outputs 1 and 7. */
    temp1=xC1S7*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC7S1*irot_input_y;
    temp2=DOROUND(temp2);
    temp2>>=16;
    op[1*8] = (ogg_int16_t) (temp1 - temp2);
    
    temp1=xC7S1*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC1S7*irot_input_y ;
    temp2=DOROUND(temp2);
    temp2>>=16;
    op[7*8] = (ogg_int16_t) (temp1 + temp2);
    
    /* Define inputs to rotation for outputs 3 and 5 */
    irot_input_x = id07 - icommon_product1;
    irot_input_y = id34 - icommon_product2;
    
    /* Apply rotation for outputs 3 and 5. */
    temp1=xC3S5*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC5S3*irot_input_y ;
    temp2=DOROUND(temp2);
    temp2>>=16;
    op[3*8] = (ogg_int16_t) (temp1 - temp2) ;

    temp1=xC5S3*irot_input_x;
    temp1=DOROUND(temp1);
    temp1>>=16;
    temp2=xC3S5*irot_input_y;
    temp2=DOROUND(temp2);
    temp2>>=16;
    op[5*8] = (ogg_int16_t) (temp1 + temp2);
    
    /* Increment data pointer for next column.  */
    ip ++;
    op ++;
  }
}

<p><p>1.1                  theora/lib/dct_decode.c

Index: dct_decode.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: dct_decode.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <ogg/ogg.h>
#include "encoder_internal.h"

<p>#define GOLDEN_FRAME_THRESH_Q   50
#define PUL 8
#define PU 4
#define PUR 2
#define PL 1
#define HIGHBITDUPPED(X) (((signed short) X)  >> 15)

ogg_uint32_t LoopFilterLimitValuesV1[Q_TABLE_SIZE] = {  
  30, 25, 20, 20, 15, 15, 14, 14,
  13, 13, 12, 12, 11, 11, 10, 10, 
  9,  9,  8,  8,  7,  7,  7,  7,
  6,  6,  6,  6,  5,  5,  5,  5,
  4,  4,  4,  4,  3,  3,  3,  3,  
  2,  2,  2,  2,  2,  2,  2,  2,  
  0,  0,  0,  0,  0,  0,  0,  0,  
  0,  0,  0,  0,  0,  0,  0,  0 
};

ogg_uint32_t LoopFilterLimitValuesV2[Q_TABLE_SIZE] = {  
  30, 25, 20, 20, 15, 15, 14, 14,
  13, 13, 12, 12, 11, 11, 10, 10, 
  9,  9,  8,  8,  7,  7,  7,  7,
  6,  6,  6,  6,  5,  5,  5,  5,
  4,  4,  4,  4,  3,  3,  3,  3,  
  2,  2,  2,  2,  2,  2,  2,  2,  
  2,  2,  2,  2,  2,  2,  2,  2,  
  1,  1,  1,  1,  1,  1,  1,  1 
};

tatic int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };

ogg_int32_t *SetupBoundingValueArray_Generic(PB_INSTANCE *pbi, 
                                             ogg_int32_t FLimit){
  ogg_int32_t * BoundingValuePtr;
  ogg_int32_t i;
  
  BoundingValuePtr = &pbi->FiltBoundingValue[256];
  /* Set up the bounding value array. */
  memset ( pbi->FiltBoundingValue, 0, (512*sizeof(*pbi->FiltBoundingValue)) );
  for ( i = 0; i < FLimit; i++ ){
    BoundingValuePtr[-i-FLimit] = (-FLimit+i);
    BoundingValuePtr[-i] = -i;
    BoundingValuePtr[i] = i;
    BoundingValuePtr[i+FLimit] = FLimit-i;
  }
  
  return BoundingValuePtr;
}

void SetupLoopFilter(PB_INSTANCE *pbi){
  ogg_int32_t FLimit; 
  
  FLimit = LoopFilterLimitValuesV2[pbi->FrameQIndex];
  pbi->BoundingValuePtr = SetupBoundingValueArray_Generic(pbi, FLimit);
}

void CopyBlock(unsigned char *src, 
               unsigned char *dest, 
               unsigned int srcstride){
  unsigned char *s = src;
  unsigned char *d = dest;
  unsigned int stride = srcstride;
  
  int j;
  for ( j = 0; j < 8; j++ ){
    ((ogg_uint32_t*)d)[0] = ((ogg_uint32_t*)s)[0];
    ((ogg_uint32_t*)d)[1] = ((ogg_uint32_t*)s)[1];
    s+=stride;
    d+=stride;
  }
}

void ExpandKFBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){
  ogg_uint32_t ReconPixelsPerLine;
  ogg_int32_t     ReconPixelIndex;  

  /* Select the appropriate inverse Q matrix and line stride */
  if ( FragmentNumber<(ogg_int32_t)pbi->YPlaneFragments ){
    ReconPixelsPerLine = pbi->Configuration.YStride;
    pbi->dequant_coeffs = pbi->dequant_Y_coeffs;
  }else{
    ReconPixelsPerLine = pbi->Configuration.UVStride;
    pbi->dequant_coeffs = pbi->dequant_UV_coeffs;
  }
    
  /* Set up pointer into the quantisation buffer. */
  pbi->quantized_list = &pbi->QFragData[FragmentNumber][0];
  
  /* Invert quantisation and DCT to get pixel data. */
  switch(pbi->FragCoefEOB[FragmentNumber]){
  case 0:case 1:
    IDct1( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
    break;
  case 2: case 3:case 4:case 5:case 6:case 7:case 8: case 9:case 10:
    IDct10( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
    break;
  default:
    IDctSlow( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
  }

  /* Convert fragment number to a pixel offset in a reconstruction buffer. */
  ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];
  
  /* Get the pixel index for the first pixel in the fragment. */
  ReconIntra( pbi, (unsigned char *)(&pbi->ThisFrameRecon[ReconPixelIndex]), 
              (ogg_uint16_t *)pbi->ReconDataBuffer, ReconPixelsPerLine );
  
}

void ExpandBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){
  unsigned char *LastFrameRecPtr;   /* Pointer into previous frame
                                       reconstruction. */
  unsigned char *LastFrameRecPtr2;  /* Pointer into previous frame
                                       reconstruction for 1/2 pixel MC. */
  
  ogg_uint32_t   ReconPixelsPerLine; /* Pixels per line */
  ogg_int32_t    ReconPixelIndex;    /* Offset for block into a
                                        reconstruction buffer */
  ogg_int32_t    ReconPtr2Offset;    /* Offset for second
                                        reconstruction in half pixel
                                        MC */
  ogg_int32_t    MVOffset;           /* Baseline motion vector offset */
  ogg_int32_t    MvShift  ;          /* Shift to correct to 1/2 or 1/4 pixel */
  ogg_int32_t    MvModMask;          /* Mask to determine whether 1/2
                                        pixel is used */
  
  /* Get coding mode for this block */
  if ( GetFrameType(pbi) == BASE_FRAME ){
    pbi->CodingMode = CODE_INTRA;
  }else{
    /* Get Motion vector and mode for this block. */
    pbi->CodingMode = pbi->FragCodingMethod[FragmentNumber];
  }

  /* Select the appropriate inverse Q matrix and line stride */
  if ( FragmentNumber<(ogg_int32_t)pbi->YPlaneFragments ) {
    ReconPixelsPerLine = pbi->Configuration.YStride;
    MvShift = 1;
    MvModMask = 0x00000001;
    
    /* Select appropriate dequantiser matrix. */
    if ( pbi->CodingMode == CODE_INTRA )
      pbi->dequant_coeffs = pbi->dequant_Y_coeffs;
    else
      pbi->dequant_coeffs = pbi->dequant_Inter_coeffs;
  }else{
    ReconPixelsPerLine = pbi->Configuration.UVStride;
    MvShift = 2;
    MvModMask = 0x00000003;

    /* Select appropriate dequantiser matrix. */
    if ( pbi->CodingMode == CODE_INTRA )
      pbi->dequant_coeffs = pbi->dequant_UV_coeffs;
    else
      pbi->dequant_coeffs = pbi->dequant_Inter_coeffs;
  }
    
  /* Set up pointer into the quantisation buffer. */
  pbi->quantized_list = &pbi->QFragData[FragmentNumber][0];
  
  /* Invert quantisation and DCT to get pixel data. */
  switch(pbi->FragCoefEOB[FragmentNumber]){
  case 0:case 1:
    IDct1( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
    break;
  case 2: case 3:case 4:case 5:case 6:case 7:case 8: case 9:case 10:
    IDct10( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
    break;
  default:
    IDctSlow( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
  }

  /* Convert fragment number to a pixel offset in a reconstruction buffer. */
  ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];

  /* Action depends on decode mode. */
  if ( pbi->CodingMode == CODE_INTER_NO_MV ){
    /* Inter with no motion vector */
    /* Reconstruct the pixel data using the last frame reconstruction
       and change data when the motion vector is (0,0), the recon is
       based on the lastframe without loop filtering---- for testing */
    ReconInter( pbi, &pbi->ThisFrameRecon[ReconPixelIndex], 
                &pbi->LastFrameRecon[ReconPixelIndex], 
                pbi->ReconDataBuffer, ReconPixelsPerLine );
    
  }else if ( ModeUsesMC[pbi->CodingMode] ) {
    /* The mode uses a motion vector. */
    /* Get vector from list */
    pbi->MVector.x = pbi->FragMVect[FragmentNumber].x;
    pbi->MVector.y = pbi->FragMVect[FragmentNumber].y;
    
    /* Work out the base motion vector offset and the 1/2 pixel offset
       if any.  For the U and V planes the MV specifies 1/4 pixel
       accuracy. This is adjusted to 1/2 pixel as follows ( 0->0,
       1/4->1/2, 1/2->1/2, 3/4->1/2 ). */
    MVOffset = 0;
    ReconPtr2Offset = 0;
    if ( pbi->MVector.x > 0 ){
      MVOffset = pbi->MVector.x >> MvShift;
      if ( pbi->MVector.x & MvModMask )
        ReconPtr2Offset += 1;
    } else if ( pbi->MVector.x < 0 ) {
      MVOffset -= (-pbi->MVector.x) >> MvShift;
      if ( (-pbi->MVector.x) & MvModMask )
        ReconPtr2Offset -= 1;
    }

    if ( pbi->MVector.y > 0 ){
      MVOffset += (pbi->MVector.y >>  MvShift) * ReconPixelsPerLine;
      if ( pbi->MVector.y & MvModMask )
        ReconPtr2Offset += ReconPixelsPerLine;
    } else if ( pbi->MVector.y < 0 ){
      MVOffset -= ((-pbi->MVector.y) >> MvShift) * ReconPixelsPerLine;
      if ( (-pbi->MVector.y) & MvModMask )
        ReconPtr2Offset -= ReconPixelsPerLine;
    }
            
    /* Set up the first of the two reconstruction buffer pointers. */
    if ( pbi->CodingMode==CODE_GOLDEN_MV ) {
      LastFrameRecPtr = &pbi->GoldenFrame[ReconPixelIndex] + MVOffset;
    }else{
      LastFrameRecPtr = &pbi->LastFrameRecon[ReconPixelIndex] + MVOffset;
    }
            
    /* Set up the second of the two reconstruction pointers. */
    LastFrameRecPtr2 = LastFrameRecPtr + ReconPtr2Offset;
    
    /* Select the appropriate reconstruction function */
    if ( (int)(LastFrameRecPtr - LastFrameRecPtr2) == 0 ) {
      /* Reconstruct the pixel dats from the reference frame and change data
         (no half pixel in this case as the two references were the same. */
      ReconInter( pbi, &pbi->ThisFrameRecon[ReconPixelIndex], 
                  LastFrameRecPtr, pbi->ReconDataBuffer, 
                  ReconPixelsPerLine );
    }else{
      /* Fractional pixel reconstruction. */
      /* Note that we only use two pixels per reconstruction even for
         the diagonal. */
      ReconInterHalfPixel2( pbi,&pbi->ThisFrameRecon[ReconPixelIndex], 
                            LastFrameRecPtr, LastFrameRecPtr2, 
                            pbi->ReconDataBuffer, ReconPixelsPerLine );
    }
  } else if ( pbi->CodingMode == CODE_USING_GOLDEN ){
    /* Golden frame with motion vector */
    /* Reconstruct the pixel data using the golden frame
       reconstruction and change data */
    ReconInter( pbi, &pbi->ThisFrameRecon[ReconPixelIndex], 
                &pbi->GoldenFrame[ ReconPixelIndex ], 
                pbi->ReconDataBuffer, ReconPixelsPerLine );
  } else {
    /* Simple Intra coding */
    /* Get the pixel index for the first pixel in the fragment. */
    ReconIntra( pbi, &pbi->ThisFrameRecon[ReconPixelIndex], 
                pbi->ReconDataBuffer, ReconPixelsPerLine );
  }
}

void UpdateUMV_HBorders( PB_INSTANCE *pbi, unsigned char * DestReconPtr, 
                         ogg_uint32_t  PlaneFragOffset ) {
  ogg_uint32_t  i;
  ogg_uint32_t  PixelIndex;
  
  ogg_uint32_t  PlaneStride;
  ogg_uint32_t  BlockVStep;
  ogg_uint32_t  PlaneFragments;
  ogg_uint32_t  LineFragments;
  ogg_uint32_t  PlaneBorderWidth;
  
  unsigned char   *SrcPtr1;  
  unsigned char   *SrcPtr2;  
  unsigned char   *DestPtr1; 
  unsigned char   *DestPtr2; 
  
  /* Work out various plane specific values */
  if ( PlaneFragOffset == 0 ) {
    /* Y Plane */
    BlockVStep = (pbi->Configuration.YStride * 
                  (pbi->Configuration.VFragPixels - 1));
    PlaneStride = pbi->Configuration.YStride;
    PlaneBorderWidth = UMV_BORDER;
    PlaneFragments = pbi->YPlaneFragments;
    LineFragments = pbi->HFragments;
  }else{
    /* U or V plane. */
    BlockVStep = (pbi->Configuration.UVStride * 
                  (pbi->Configuration.VFragPixels - 1));
    PlaneStride = pbi->Configuration.UVStride;
    PlaneBorderWidth = UMV_BORDER / 2;
    PlaneFragments = pbi->UVPlaneFragments;
    LineFragments = pbi->HFragments / 2;
  }

  /* Setup the source and destination pointers for the top and bottom
     borders */
  PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset];
  SrcPtr1 = &DestReconPtr[ PixelIndex - PlaneBorderWidth ];
  DestPtr1 = SrcPtr1 - (PlaneBorderWidth * PlaneStride);
  
  PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset + 
                                           PlaneFragments - LineFragments] + 
    BlockVStep;
  SrcPtr2 = &DestReconPtr[ PixelIndex - PlaneBorderWidth];
  DestPtr2 = SrcPtr2 + PlaneStride;

  /* Now copy the top and bottom source lines into each line of the
     respective borders */
  for ( i = 0; i < PlaneBorderWidth; i++ ) {
    memcpy( DestPtr1, SrcPtr1, PlaneStride );
    memcpy( DestPtr2, SrcPtr2, PlaneStride );
    DestPtr1 += PlaneStride;
    DestPtr2 += PlaneStride;
  }
}

void UpdateUMV_VBorders( PB_INSTANCE *pbi, unsigned char * DestReconPtr, 
                         ogg_uint32_t  PlaneFragOffset ){
  ogg_uint32_t  i;
  ogg_uint32_t  PixelIndex;
  
  ogg_uint32_t  PlaneStride;
  ogg_uint32_t  LineFragments;
  ogg_uint32_t  PlaneBorderWidth;
  ogg_uint32_t   PlaneHeight;
  
  unsigned char   *SrcPtr1; 
  unsigned char   *SrcPtr2; 
  unsigned char   *DestPtr1;
  unsigned char   *DestPtr2;

  /* Work out various plane specific values */
  if ( PlaneFragOffset == 0 ) {
    /* Y Plane */
    PlaneStride = pbi->Configuration.YStride;
    PlaneBorderWidth = UMV_BORDER;
    LineFragments = pbi->HFragments;
    PlaneHeight = pbi->Configuration.VideoFrameHeight;
  }else{
    /* U or V plane. */
    PlaneStride = pbi->Configuration.UVStride;
    PlaneBorderWidth = UMV_BORDER / 2;
    LineFragments = pbi->HFragments / 2;
    PlaneHeight = pbi->Configuration.VideoFrameHeight / 2;
  }
  
  /* Setup the source data values and destination pointers for the
     left and right edge borders */
  PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset];
  SrcPtr1 = &DestReconPtr[ PixelIndex ];
  DestPtr1 = &DestReconPtr[ PixelIndex - PlaneBorderWidth ];
  
  PixelIndex = pbi->recon_pixel_index_table[PlaneFragOffset + 
                                           LineFragments - 1] + 
    (pbi->Configuration.HFragPixels - 1);
  SrcPtr2 = &DestReconPtr[ PixelIndex ];
  DestPtr2 = &DestReconPtr[ PixelIndex + 1 ];

  /* Now copy the top and bottom source lines into each line of the
     respective borders */
  for ( i = 0; i < PlaneHeight; i++ ) {
    memset( DestPtr1, SrcPtr1[0], PlaneBorderWidth );
    memset( DestPtr2, SrcPtr2[0], PlaneBorderWidth );
    SrcPtr1 += PlaneStride;
    SrcPtr2 += PlaneStride;
    DestPtr1 += PlaneStride;
    DestPtr2 += PlaneStride;
  }
}

void UpdateUMVBorder( PB_INSTANCE *pbi, unsigned char * DestReconPtr ) {
  ogg_uint32_t  PlaneFragOffset;
  
  /* Y plane */
  PlaneFragOffset = 0;
  UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
  UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
  
  /* Then the U and V Planes */
  PlaneFragOffset = pbi->YPlaneFragments;
  UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
  UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
  
  PlaneFragOffset = pbi->YPlaneFragments + pbi->UVPlaneFragments;   
  UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
  UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
}

void CopyRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr, 
                unsigned char * SrcReconPtr ) {
  ogg_uint32_t  i;
  ogg_uint32_t	PlaneLineStep; /* Pixels per line */
  ogg_uint32_t  PixelIndex;
  
  unsigned char  *SrcPtr;      /* Pointer to line of source image data */
  unsigned char  *DestPtr;     /* Pointer to line of destination image data */
  
  /* Copy over only updated blocks.*/
  
  /* First Y plane */
  PlaneLineStep = pbi->Configuration.YStride;
  for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
    if ( pbi->display_fragments[i] ) {
      PixelIndex = pbi->recon_pixel_index_table[i];
      SrcPtr = &SrcReconPtr[ PixelIndex ];
      DestPtr = &DestReconPtr[ PixelIndex ];
      
      CopyBlock(SrcPtr, DestPtr, PlaneLineStep);
    }
  }
  
  /* Then U and V */
  PlaneLineStep = pbi->Configuration.UVStride;
  for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) {
    if ( pbi->display_fragments[i] ) {
      PixelIndex = pbi->recon_pixel_index_table[i];
      SrcPtr = &SrcReconPtr[ PixelIndex ];
      DestPtr = &DestReconPtr[ PixelIndex ];
      
      CopyBlock(SrcPtr, DestPtr, PlaneLineStep);
      
    }
  }

  /* We may need to update the UMV border */
  UpdateUMVBorder(pbi, DestReconPtr);
  
}

void CopyNotRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr, 
                   unsigned char * SrcReconPtr ) {
  ogg_uint32_t  i;
  ogg_uint32_t	PlaneLineStep; /* Pixels per line */
  ogg_uint32_t  PixelIndex;
  
  unsigned char  *SrcPtr;      /* Pointer to line of source image data */
  unsigned char  *DestPtr;     /* Pointer to line of destination image data*/

  /* Copy over only updated blocks. */

  /* First Y plane */
  PlaneLineStep = pbi->Configuration.YStride;
  for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
    if ( !pbi->display_fragments[i] ) {
      PixelIndex = pbi->recon_pixel_index_table[i];
      SrcPtr = &SrcReconPtr[ PixelIndex ];
      DestPtr = &DestReconPtr[ PixelIndex ];
      
      CopyBlock(SrcPtr, DestPtr, PlaneLineStep);
    }
  }
  
  /* Then U and V */
  PlaneLineStep = pbi->Configuration.UVStride;
  for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) {
    if ( !pbi->display_fragments[i] ) {
      PixelIndex = pbi->recon_pixel_index_table[i];
      SrcPtr = &SrcReconPtr[ PixelIndex ];
      DestPtr = &DestReconPtr[ PixelIndex ];
      
      CopyBlock(SrcPtr, DestPtr, PlaneLineStep);
      
    }
  }
  
  /*  We may need to update the UMV border */
  UpdateUMVBorder(pbi, DestReconPtr);
  
}

void ExpandToken( PB_INSTANCE *pbi, Q_LIST_ENTRY * ExpandedBlock, 
                  unsigned char * CoeffIndex, ogg_uint32_t Token, 
                  ogg_int32_t ExtraBits ){
  /* Is the token is a combination run and value token. */
  if ( Token >= DCT_RUN_CATEGORY1 ){
    /* Expand the token and additional bits to a zero run length and
       data value.  */
    if ( Token < DCT_RUN_CATEGORY2 ) {   
      /* Decoding method depends on token */
      if ( Token < DCT_RUN_CATEGORY1B ) {
        /* Step on by the zero run length */
        *CoeffIndex += (unsigned char)((Token - DCT_RUN_CATEGORY1) + 1);

        /* The extra bit determines the sign. */
        if ( ExtraBits & 0x01 )
          ExpandedBlock[*CoeffIndex] = -1;
        else
          ExpandedBlock[*CoeffIndex] = 1;
      } else if ( Token == DCT_RUN_CATEGORY1B ) {
        /* Bits 0-1 determines the zero run length */
        *CoeffIndex += (6 + (ExtraBits & 0x03));
        
        /* Bit 2 determines the sign */
        if ( ExtraBits & 0x04 )
          ExpandedBlock[*CoeffIndex] = -1;
        else
          ExpandedBlock[*CoeffIndex] = 1;
      }else{
        /* Bits 0-2 determines the zero run length */
        *CoeffIndex += (10 + (ExtraBits & 0x07));
        
        /* Bit 3 determines the sign */
        if ( ExtraBits & 0x08 )
          ExpandedBlock[*CoeffIndex] = -1;
        else
          ExpandedBlock[*CoeffIndex] = 1;
      }
    }else{   
      /* If token == DCT_RUN_CATEGORY2 we have a single 0 followed by
         a value */
      if ( Token == DCT_RUN_CATEGORY2 ){
        /* Step on by the zero run length */
        *CoeffIndex += 1;
        
        /* Bit 1 determines sign, bit 0 the value */
        if ( ExtraBits & 0x02 )
          ExpandedBlock[*CoeffIndex] = -(2 + (ExtraBits & 0x01));
        else
          ExpandedBlock[*CoeffIndex] = 2 + (ExtraBits & 0x01);
      }else{
        /* else we have 2->3 zeros followed by a value */
        /* Bit 0 determines the zero run length */
        *CoeffIndex += 2 + (ExtraBits & 0x01);
        
        /* Bit 2 determines the sign, bit 1 the value */
        if ( ExtraBits & 0x04 )
          ExpandedBlock[*CoeffIndex] = -(2 + ((ExtraBits & 0x02) >> 1));
        else
          ExpandedBlock[*CoeffIndex] = 2 + ((ExtraBits & 0x02) >> 1);
      }
    }
    
    /* Step on over value */
    *CoeffIndex += 1;
    
  } else if ( Token == DCT_SHORT_ZRL_TOKEN ) {
    /* Token is a ZRL token so step on by the appropriate number of zeros */
    *CoeffIndex += ExtraBits + 1;
  } else if ( Token == DCT_ZRL_TOKEN ) {
    /* Token is a ZRL token so step on by the appropriate number of zeros */
    *CoeffIndex += ExtraBits + 1;
  } else if ( Token < LOW_VAL_TOKENS ) {
    /* Token is a small single value token. */
    switch ( Token ) {
    case ONE_TOKEN:
      ExpandedBlock[*CoeffIndex] = 1;
      break;
    case MINUS_ONE_TOKEN:
      ExpandedBlock[*CoeffIndex] = -1;
      break;
    case TWO_TOKEN:
      ExpandedBlock[*CoeffIndex] = 2;
      break;
    case MINUS_TWO_TOKEN:
      ExpandedBlock[*CoeffIndex] = -2;
      break;
    }
    
    /* Step on the coefficient index. */
    *CoeffIndex += 1;
  }else{
    /* Token is a larger single value token */
    /* Expand the token and additional bits to a data value. */
    if ( Token < DCT_VAL_CATEGORY3 ) {   
      /* Offset from LOW_VAL_TOKENS determines value */
      Token = Token - LOW_VAL_TOKENS;
      
      /* Extra bit determines sign */
      if ( ExtraBits )
        ExpandedBlock[*CoeffIndex] = 
          -((Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN));
      else
        ExpandedBlock[*CoeffIndex] = 
          (Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN);
    } else if ( Token == DCT_VAL_CATEGORY3 ) {   
      /* Bit 1 determines sign, Bit 0 the value */
      if ( ExtraBits & 0x02 )
        ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT3_MIN + (ExtraBits & 0x01));
      else
        ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT3_MIN + (ExtraBits & 0x01);
    } else if ( Token == DCT_VAL_CATEGORY4 ) {   
      /* Bit 2 determines sign, Bit 0-1 the value */
      if ( ExtraBits & 0x04 )
        ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT4_MIN + (ExtraBits & 0x03));
      else
        ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT4_MIN + (ExtraBits & 0x03);
    } else if ( Token == DCT_VAL_CATEGORY5 ) {
      /* Bit 3 determines sign, Bit 0-2 the value */
      if ( ExtraBits & 0x08 )
        ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT5_MIN + (ExtraBits & 0x07));
      else
        ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT5_MIN + (ExtraBits & 0x07);
    } else if ( Token == DCT_VAL_CATEGORY6 ) {
      /* Bit 4 determines sign, Bit 0-3 the value */
      if ( ExtraBits & 0x10 )
        ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F));
      else
        ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F);
    } else if ( Token == DCT_VAL_CATEGORY7 ) {
      /* Bit 5 determines sign, Bit 0-4 the value */
      if ( ExtraBits & 0x20 )
        ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F));
      else
        ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F);
    } else if ( Token == DCT_VAL_CATEGORY8 ) {
      /* Bit 9 determines sign, Bit 0-8 the value */
      if ( ExtraBits & 0x200 )
        ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF));
      else
        ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF);
    }
    
    /* Step on the coefficient index. */
    *CoeffIndex += 1;
  }
}

void ClearDownQFragData(PB_INSTANCE *pbi){
  ogg_int32_t       i,j;
  Q_LIST_ENTRY *    QFragPtr;
  
  for ( i = 0; i < pbi->CodedBlockIndex; i++ ) {
    /* Get the linear index for the current fragment. */
    QFragPtr = pbi->QFragData[pbi->CodedBlockList[i]];
    for ( j = 0; j < 64; j++ ) QFragPtr[j]  = 0;
  }
}

void FilterHoriz(PB_INSTANCE *pbi, unsigned char * PixelPtr, 
                         ogg_int32_t LineLength, 
                         ogg_int32_t *BoundingValuePtr){
  ogg_int32_t j;
  ogg_int32_t FiltVal;
  
  for ( j = 0; j < 8; j++ ){            
    FiltVal =  ( PixelPtr[0] ) - 
      ( PixelPtr[1] * 3 ) +
      ( PixelPtr[2] * 3 ) - 
      ( PixelPtr[3] );
    
    FiltVal = BoundingValuePtr[(FiltVal + 4) >> 3];
    
    PixelPtr[1] = clamp255(PixelPtr[1] + FiltVal);
    PixelPtr[2] = clamp255(PixelPtr[2] - FiltVal);
    
    PixelPtr += LineLength;
  }
}

void FilterVert(PB_INSTANCE *pbi, unsigned char * PixelPtr, 
                        ogg_int32_t LineLength, 
                        ogg_int32_t *BoundingValuePtr){
  ogg_int32_t j;
  ogg_int32_t FiltVal;
  
  /* the math was correct, but negative array indicies are forbidden
     by ANSI/C99 and will break optimization on several modern
     compilers */

  PixelPtr -= 2*LineLength;

  for ( j = 0; j < 8; j++ ) {            
    FiltVal = ( (ogg_int32_t)PixelPtr[0] ) - 
      ( (ogg_int32_t)PixelPtr[LineLength] * 3 ) + 
      ( (ogg_int32_t)PixelPtr[2 * LineLength] * 3 ) - 
      ( (ogg_int32_t)PixelPtr[3 * LineLength] );
    
    FiltVal = BoundingValuePtr[(FiltVal + 4) >> 3];
    
    PixelPtr[LineLength] = clamp255(PixelPtr[LineLength] + FiltVal);
    PixelPtr[2 * LineLength] = clamp255(PixelPtr[2*LineLength] - FiltVal);
    
    PixelPtr ++;
  }
}

void LoopFilter(PB_INSTANCE *pbi){
  ogg_int32_t i;
  
  unsigned long uvHFragments = pbi->HFragments >> 1;
  ogg_int32_t * BoundingValuePtr;
  int FragsAcross=pbi->HFragments;	
  int FromFragment,ToFragment;
  int FragsDown = pbi->VFragments;
  ogg_int32_t LineFragments;
  ogg_int32_t LineLength;
  unsigned char BlockHeight = (unsigned char)pbi->Configuration.VFragPixels;
  unsigned char BlockWidth = (unsigned char)pbi->Configuration.HFragPixels;
  ogg_int32_t FLimit; 
  int QIndex;
  int j,m,n;
  
  /* Set the limit value for the loop filter based upon the current
     quantizer. */
  QIndex = Q_TABLE_SIZE - 1;
  while ( QIndex >= 0 ) {
    if ( (QIndex == 0) || 
         ( pbi->QThreshTable[QIndex] >= pbi->ThisFrameQualityValue) )
      break;
    QIndex --;
  }
  
  /* Encoder version specific clause */
  FLimit = LoopFilterLimitValuesV1[QIndex];
  
  if ( FLimit == 0 ) return;
  
  BoundingValuePtr = SetupBoundingValueArray_Generic(pbi, FLimit);
 
  
  for ( j = 0; j < 3 ; j++){
    switch(j) {
    case 0: /* y */
      FromFragment = 0;
      ToFragment = pbi->YPlaneFragments;
      FragsAcross = pbi->HFragments;
      FragsDown = pbi->VFragments;
      LineLength = pbi->Configuration.YStride;
      LineFragments = pbi->HFragments;
      break;
    case 1: /* u */
      FromFragment = pbi->YPlaneFragments;
      ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ;
      FragsAcross = pbi->HFragments >> 1;
      FragsDown = pbi->VFragments >> 1;
      LineLength = pbi->Configuration.UVStride;
      LineFragments = pbi->HFragments / 2;
      break;
    case 2: /* v */
      FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
      ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
      FragsAcross = pbi->HFragments >> 1;
      FragsDown = pbi->VFragments >> 1;
      LineLength = pbi->Configuration.UVStride;
      LineFragments = pbi->HFragments / 2;
      break;
    }
    
    i=FromFragment;
    
    /**************************************************************
     First Row 
    **************************************************************/
    /* first column conditions */
    /* only do 2 prediction if fragment coded and on non intra or if
       all fragments are intra */
    if( pbi->display_fragments[i]){
      /* Filter right hand border only if the block to the right is
         not coded */
      if ( !pbi->display_fragments[ i + 1 ] ){
        FilterHoriz(pbi, pbi->LastFrameRecon+
                    pbi->recon_pixel_index_table[i]+6, 
                    LineLength, BoundingValuePtr);
      }
      
      /* Bottom done if next row set */
      if( !pbi->display_fragments[ i + LineFragments] ){
        FilterVert(pbi, pbi->LastFrameRecon+
                   pbi->recon_pixel_index_table[i+LineFragments], 
                   LineLength, BoundingValuePtr);
      }		
    }	
    i++;
    
    /***************************************************************/
    /* middle columns  */
    for ( n = 1 ; n < FragsAcross - 1 ; n++, i++) {
      if( pbi->display_fragments[i]){
        /* Filter Left edge always */
        FilterHoriz(pbi, pbi->LastFrameRecon+
                    pbi->recon_pixel_index_table[i]-2, 
                    LineLength, BoundingValuePtr);
        
        /* Filter right hand border only if the block to the right is
           not coded */
        if ( !pbi->display_fragments[ i + 1 ] ){
          FilterHoriz(pbi, pbi->LastFrameRecon+
                      pbi->recon_pixel_index_table[i]+6, 
                      LineLength, BoundingValuePtr);
        }
        
        /* Bottom done if next row set */
        if( !pbi->display_fragments[ i + LineFragments] ){
          FilterVert(pbi, pbi->LastFrameRecon+
                     pbi->recon_pixel_index_table[i + LineFragments],
                     LineLength, BoundingValuePtr);
        }
                                                        
      } 			
    }
                
    /***************************************************************/
    /* Last Column */
    if( pbi->display_fragments[i]){
      /* Filter Left edge always */
      FilterHoriz(pbi, pbi->LastFrameRecon+
                  pbi->recon_pixel_index_table[i] - 2 , 
                  LineLength, BoundingValuePtr);
      
      /* Bottom done if next row set */
      if( !pbi->display_fragments[ i + LineFragments] ){
        FilterVert(pbi, pbi->LastFrameRecon+
                   pbi->recon_pixel_index_table[i + LineFragments], 
                   LineLength, BoundingValuePtr);
      }		
    }	
    i++;

    /***************************************************************/
    /* Middle Rows */
    /***************************************************************/
    for ( m = 1 ; m < FragsDown-1 ; m++) {

      /*****************************************************************/
      /* first column conditions */
      /* only do 2 prediction if fragment coded and on non intra or if
         all fragments are intra */
      if( pbi->display_fragments[i]){
        /* TopRow is always done */
        FilterVert(pbi, pbi->LastFrameRecon+
                   pbi->recon_pixel_index_table[i], 
                   LineLength, BoundingValuePtr);
        
        /* Filter right hand border only if the block to the right is
           not coded */
        if ( !pbi->display_fragments[ i + 1 ] ){
          FilterHoriz(pbi, pbi->LastFrameRecon+
                      pbi->recon_pixel_index_table[i] + 6, 
                      LineLength, BoundingValuePtr);
        }

        /* Bottom done if next row set */
        if( !pbi->display_fragments[ i + LineFragments] ){
          FilterVert(pbi, pbi->LastFrameRecon+
                     pbi->recon_pixel_index_table[i + LineFragments], 
                     LineLength, BoundingValuePtr);
        }
      }
      i++;

      /*****************************************************************/
      /* middle columns  */
      for ( n = 1 ; n < FragsAcross - 1 ; n++, i++){
        if( pbi->display_fragments[i]){
          /* Filter Left edge always */
          FilterHoriz(pbi, pbi->LastFrameRecon+
                      pbi->recon_pixel_index_table[i] - 2, 
                      LineLength, BoundingValuePtr);
          
          /* TopRow is always done */
          FilterVert(pbi, pbi->LastFrameRecon+
                     pbi->recon_pixel_index_table[i], 
                     LineLength, BoundingValuePtr);

          /* Filter right hand border only if the block to the right
             is not coded */
          if ( !pbi->display_fragments[ i + 1 ] ){
            FilterHoriz(pbi, pbi->LastFrameRecon+
                        pbi->recon_pixel_index_table[i] + 6,
                        LineLength, BoundingValuePtr);
          }
          
          /* Bottom done if next row set */
          if( !pbi->display_fragments[ i + LineFragments] ){
            FilterVert(pbi, pbi->LastFrameRecon+
                       pbi->recon_pixel_index_table[i + LineFragments],
                       LineLength, BoundingValuePtr);
          }
        }
      }

      /******************************************************************/
      /* Last Column */
      if( pbi->display_fragments[i]){
        /* Filter Left edge always*/
        FilterHoriz(pbi, pbi->LastFrameRecon+
                    pbi->recon_pixel_index_table[i] - 2,
                    LineLength, BoundingValuePtr);
        
        /* TopRow is always done */
        FilterVert(pbi, pbi->LastFrameRecon+
                   pbi->recon_pixel_index_table[i], 
                   LineLength, BoundingValuePtr);
        
        /* Bottom done if next row set */
        if( !pbi->display_fragments[ i + LineFragments] ){
          FilterVert(pbi, pbi->LastFrameRecon+
                     pbi->recon_pixel_index_table[i + LineFragments],
                     LineLength, BoundingValuePtr);
        }
      }
      i++;

    }
                
    /*******************************************************************/
    /* Last Row  */

    /* first column conditions */
    /* only do 2 prediction if fragment coded and on non intra or if
       all fragments are intra */
    if( pbi->display_fragments[i]){
                        
      /* TopRow is always done */
      FilterVert(pbi, pbi->LastFrameRecon+
                 pbi->recon_pixel_index_table[i], 
                 LineLength, BoundingValuePtr);
      
      /* Filter right hand border only if the block to the right is
         not coded */
      if ( !pbi->display_fragments[ i + 1 ] ){
        FilterHoriz(pbi, pbi->LastFrameRecon+
                    pbi->recon_pixel_index_table[i] + 6,
                    LineLength, BoundingValuePtr);
      }		
    }		
    i++;
                
    /******************************************************************/
    /* middle columns  */
    for ( n = 1 ; n < FragsAcross - 1 ; n++, i++){
      if( pbi->display_fragments[i]){
        /* Filter Left edge always */
        FilterHoriz(pbi, pbi->LastFrameRecon+
                    pbi->recon_pixel_index_table[i] - 2, 
                    LineLength, BoundingValuePtr);
        
        /* TopRow is always done */
        FilterVert(pbi, pbi->LastFrameRecon+
                   pbi->recon_pixel_index_table[i],
                   LineLength, BoundingValuePtr);
                                
        /* Filter right hand border only if the block to the right is
           not coded */
        if ( !pbi->display_fragments[ i + 1 ] ){
          FilterHoriz(pbi, pbi->LastFrameRecon+
                      pbi->recon_pixel_index_table[i] + 6, 
                      LineLength, BoundingValuePtr);
        }			
      }		
    }
                
    /******************************************************************/
    /* Last Column */
    if( pbi->display_fragments[i]){
      /* Filter Left edge always */
      FilterHoriz(pbi, pbi->LastFrameRecon+
                  pbi->recon_pixel_index_table[i] - 2,
                  LineLength, BoundingValuePtr);
      
      /* TopRow is always done */
      FilterVert(pbi, pbi->LastFrameRecon+
                 pbi->recon_pixel_index_table[i],
                 LineLength, BoundingValuePtr);
      
    } 	
    i++;
  }
}

void ReconRefFrames (PB_INSTANCE *pbi){
  ogg_int32_t i;
  ogg_int32_t FragIndex;
  unsigned char *SwapReconBuffersTemp;
  
  unsigned long uvHFragments = pbi->HFragments >> 1;
  
  short pc[16][6]={
    {0,0,0,0,0,0},	
    {0,0,0,1,0,0},
    {0,0,1,0,0,0},
    {0,0,53,75,7,127},
    {0,1,0,0,0,0},
    {0,1,0,1,1,1},
    {0,1,0,0,0,0},
    {0,0,53,75,7,127},
    {1,0,0,0,0,0},
    {0,0,0,1,0,0},
    {1,0,1,0,1,1},
    {0,0,53,75,7,127},
    {0,1,0,0,0,0},
    {-26,29,0,29,5,31},
    {3,10,3,0,4,15},
    {-26,29,0,29,5,31}
  };
  int fl,ful,fu,fur;
  int vl,vul,vu,vur;
  int l,ul,u,ur;
  short wpc;
  short Mode2Frame[] = { 1,0,1,1,1,2,2,1 };
  short Last[3];
  short PredictedDC;
  int FragsAcross=pbi->HFragments;	
  int FromFragment,ToFragment;
  int FragsDown = pbi->VFragments;

  int WhichFrame;
  int WhichCase;
  int j,k,m,n;

  struct SearchPoints{
    int RowOffset;
    int ColOffset;
  } DCSearchPoints[]={
    {0,-2},{-2,0},{-1,-2},{-2,-1},{-2,1},{-1,2},{-2,-2},{-2,2},{0,-3},
    {-3,0},{-1,-3},{-3,-1},{-3,1},{-1,3},{-2,-3},{-3,-2},{-3,2},{-2,3},
    {0,-4},{-4,0},{-1,-4},{-4,-1},{-4,1},{-1,4},{-3,-3},{-3,3}
  };
        
  int DCSearchPointCount = 0;
  void (*ExpandBlockA) ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber );
  
  if ( GetFrameType(pbi) == BASE_FRAME )
    ExpandBlockA=ExpandKFBlock;
  else
    ExpandBlockA=ExpandBlock;

  SetupLoopFilter(pbi);
  
  /* for y,u,v */
  for ( j = 0; j < 3 ; j++) {
    /* pick which fragments based on Y, U, V */
    switch(j){
    case 0: /* y */
      FromFragment = 0;
      ToFragment = pbi->YPlaneFragments;
      FragsAcross = pbi->HFragments;
      FragsDown = pbi->VFragments;
      break;
    case 1: /* u */
      FromFragment = pbi->YPlaneFragments;
      ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ;
      FragsAcross = pbi->HFragments >> 1;
      FragsDown = pbi->VFragments >> 1;
      break;
    case 2: /* v */
      FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
      ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
      FragsAcross = pbi->HFragments >> 1;
      FragsDown = pbi->VFragments >> 1;
      break;
    }

    /* initialize our array of last used DC Components */
    for(k=0;k<3;k++)
      Last[k]=0;

    i=FromFragment;
    
    /* do prediction on all of Y, U or V */
    for ( m = 0 ; m < FragsDown ; m++) {
      for ( n = 0 ; n < FragsAcross ; n++, i++){
        
        /* only do 2 prediction if fragment coded and on non intra or
           if all fragments are intra */
        if( pbi->display_fragments[i] || (GetFrameType(pbi) == BASE_FRAME) ){
          /* Type of Fragment */	  WhichFrame = Mode2Frame[pbi->FragCodingMethod[i]];
          
          /* Check Borderline Cases */
          WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2);

          switch(WhichCase){
          case 0: /* normal case no border condition */
            
            /* calculate values left, up, up-right and up-left */
            l = i-1;
            u = i - FragsAcross;
            ur = i - FragsAcross + 1;
            ul = i - FragsAcross - 1;
            
            /* calculate values */
            vl = pbi->QFragData[l][0];
            vu = pbi->QFragData[u][0];
            vur = pbi->QFragData[ur][0];
            vul = pbi->QFragData[ul][0];
            
            /* fragment valid for prediction use if coded and it comes
               from same frame as the one we are predicting */
            fl = pbi->display_fragments[l] && 
              (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame);
            fu = pbi->display_fragments[u] && 
              (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame);
            fur = pbi->display_fragments[ur] && 
              (Mode2Frame[pbi->FragCodingMethod[ur]] == WhichFrame);
            ful = pbi->display_fragments[ul] && 
              (Mode2Frame[pbi->FragCodingMethod[ul]] == WhichFrame);

            /* calculate which predictor to use */
            wpc = (fl*PL) | (fu*PU) | (ful*PUL) | (fur*PUR);
            
            break;
            
          case 1: /* n == 0 Left Column */
            
            /* calculate values left, up, up-right and up-left */
            u = i - FragsAcross;
            ur = i - FragsAcross + 1;
            
            /* calculate values */
            vu = pbi->QFragData[u][0];
            vur = pbi->QFragData[ur][0];

            /* fragment valid for prediction if coded and it comes
               from same frame as the one we are predicting */
            fu = pbi->display_fragments[u] && 
              (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame);
            fur = pbi->display_fragments[ur] && 
              (Mode2Frame[pbi->FragCodingMethod[ur]] == WhichFrame);

            /* calculate which predictor to use */
            wpc = (fu*PU) | (fur*PUR);
            
            break;
            
          case 2: /* m == 0 Top Row */
          case 6: /* m == 0 and n+1 == FragsAcross or Top Row Right Column */
            
            /* calculate values left, up, up-right and up-left */
            l = i-1;
            
            /* calculate values */
            vl = pbi->QFragData[l][0];
            
            /* fragment valid for prediction if coded and it comes
               from same frame as the one we are predicting */
            fl = pbi->display_fragments[l] && 
              (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame);
            
            /* calculate which predictor to use */
            wpc = (fl*PL) ;
            
            break;
            
          case 3: /* n == 0 & m == 0 Top Row Left Column */
            
            wpc = 0;
            
            break;
            
          case 4: /* n+1 == FragsAcross : Right Column */
            
            /* calculate values left, up, up-right and up-left */
            l = i-1;
            u = i - FragsAcross;
            ul = i - FragsAcross - 1;
            
            /* calculate values */
            vl = pbi->QFragData[l][0];
            vu = pbi->QFragData[u][0];
            vul = pbi->QFragData[ul][0];
            
            /* fragment valid for prediction if coded and it comes
               from same frame as the one we are predicting */
            fl = pbi->display_fragments[l] && 
              (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame);
            fu = pbi->display_fragments[u] && 
              (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame);
            ful = pbi->display_fragments[ul] && 
              (Mode2Frame[pbi->FragCodingMethod[ul]] == WhichFrame);
            
            /* calculate which predictor to use */
            wpc = (fl*PL) | (fu*PU) | (ful*PUL) ;
            
            break;
            
          }
                                                  
          if(wpc==0){
            FragIndex = 1;
            
            /* find the nearest one that is coded */
            for( k = 0; k < DCSearchPointCount ; k++){
              FragIndex = i + DCSearchPoints[k].RowOffset * FragsAcross + 
                DCSearchPoints[k].ColOffset;
              
              if( FragIndex - FromFragment > 0 ) {
                if(pbi->display_fragments[FragIndex] && 
                   (Mode2Frame[pbi->FragCodingMethod[FragIndex]] == 
                    WhichFrame)){
                  pbi->QFragData[i][0] += pbi->QFragData[FragIndex][0];
                  FragIndex = 0;
                  break;
                }
              }
            }
            
            
            /* if none matched fall back to the last one ever */
            if(FragIndex){
              pbi->QFragData[i][0] += Last[WhichFrame];
            }
            
          }else{
            
            /* don't do divide if divisor is 1 or 0 */
            PredictedDC = (pc[wpc][0]*vul + pc[wpc][1] * vu + 
                           pc[wpc][2] * vur + pc[wpc][3] * vl );
            
            /* if we need to do a shift */
            if(pc[wpc][4] != 0 ){
              
              /* If negative add in the negative correction factor */
              PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);
              
              /* Shift in lieu of a divide */
              PredictedDC >>= pc[wpc][4];
            }
            
            /* check for outranging on the two predictors that can outrange */
            switch(wpc){
            case 13: /* pul pu pl */
            case 15: /* pul pu pur pl */
              if( abs(PredictedDC - vu) > 128)
                PredictedDC = vu;
              else if( abs(PredictedDC - vl) > 128)
                PredictedDC = vl;
              else if( abs(PredictedDC - vul) > 128)
                PredictedDC = vul;
              
              break;
            }
            
            pbi->QFragData[i][0] += PredictedDC;
            
          }
          
          /* Save the last fragment coded for whatever frame we are
             predicting from */
          Last[WhichFrame] = pbi->QFragData[i][0];
          
          /* Inverse DCT and reconstitute buffer in thisframe */
          ExpandBlockA( pbi, i );
          
        }
      } 
    }
  }

  /* Copy the current reconstruction back to the last frame recon buffer. */
  if(pbi->CodedBlockIndex > (ogg_int32_t) (pbi->UnitFragments >> 1)){
    SwapReconBuffersTemp = pbi->ThisFrameRecon;
    pbi->ThisFrameRecon = pbi->LastFrameRecon;
    pbi->LastFrameRecon = SwapReconBuffersTemp;
    CopyNotRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon );
  }else{
    CopyRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon );
  }
         
  /* Apply a loop filter to edge pixels of updated blocks */
  LoopFilter(pbi);
        
  
  /* Reconstruct the golden frame if necessary. 
     For VFW codec only on key frames */
  if ( GetFrameType(pbi) == BASE_FRAME )
    CopyRecon( pbi, pbi->GoldenFrame, pbi->LastFrameRecon );

}

<p><p><p><p><p><p>1.1                  theora/lib/decode.c

Index: decode.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: decode.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <ogg/ogg.h>
#include "encoder_internal.h"

int GetFrameType(PB_INSTANCE *pbi){
  return pbi->FrameType; 
}

int PbBuildBitmapHeader( PB_INSTANCE *pbi, 
                         ogg_uint32_t ImageWidth, 
                         ogg_uint32_t ImageHeight ){
  if(!InitFrameDetails(pbi))return 0;
  return 1;
}

int LoadFrame(PB_INSTANCE *pbi){ 
  
  /* Load the frame header (including the frame size). */
  if ( LoadFrameHeader(pbi) ){
    /* Read in the updated block map */
    QuadDecodeDisplayFragments( pbi );
    return 1;
  }
  
  return 0;
}

int LoadFrameHeader(PB_INSTANCE *pbi){
  unsigned char  VersionByte0;    /* Must be 0 for VP30b and later */
  unsigned char  DctQMask;
  unsigned char  SpareBits;       /* Spare cfg bits */
  unsigned char  Unused;
  
  /* Is the frame and inter frame or a key frame */
  pbi->FrameType = oggpackB_read(&pbi->opb,1);
    
  /* unused bit */
  Unused = oggpackB_read(&pbi->opb,1);
  
  /* Quality (Q) index */
  DctQMask = oggpackB_read( &pbi->opb,   6 );

  /* If the frame was a base frame then read the frame dimensions and
     build a bitmap structure. */
  if ( (pbi->FrameType == BASE_FRAME) ){
    /* Read the frame dimensions bytes (0,0 indicates vp31 or later) */
    VersionByte0 = oggpackB_read( &pbi->opb,   8 );
    pbi->Vp3VersionNo = oggpackB_read( &pbi->opb,   5 );
    
    /* we don't decode version 0 either */
    if(pbi->Vp3VersionNo > CURRENT_ENCODE_VERSION) return 0;
    if(pbi->Vp3VersionNo == 0) return 0;
    
    /* Initialise version specific quantiser values */
    InitQTables( pbi );

    /* Read the type / coding method for the key frame. */
    pbi->KeyFrameType = oggpackB_read( &pbi->opb,   1 );
    
    SpareBits = oggpackB_read( &pbi->opb,   2 );
    
    InitHuffmanSet( pbi );
    
  }
        
  /* Set this frame quality value from Q Index */
  pbi->ThisFrameQualityValue = pbi->QThreshTable[DctQMask];
  
  return 1;
}

void SetFrameType( PB_INSTANCE *pbi,unsigned char FrType ){ 
  /* Set the appropriate frame type according to the request. */
  switch ( FrType ){  
    
  case BASE_FRAME:
    pbi->FrameType = FrType;
    break;
    
  default:
    pbi->FrameType = FrType;
    break;
  }
}

<p><p><p>1.1                  theora/lib/frinit.c

Index: frinit.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: frinit.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <stdlib.h>
#include <ogg/ogg.h>
#include "encoder_internal.h"

<p>void CalcPixelIndexTable( PB_INSTANCE *pbi){
  ogg_uint32_t i;
  ogg_uint32_t * PixelIndexTablePtr;
  
  /* Calculate the pixel index table for normal image buffers */
  PixelIndexTablePtr = pbi->pixel_index_table;
  for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
    PixelIndexTablePtr[ i ] = 
      ((i / pbi->HFragments) * pbi->Configuration.VFragPixels * 
       pbi->Configuration.VideoFrameWidth);  
    PixelIndexTablePtr[ i ] += 
      ((i % pbi->HFragments) * pbi->Configuration.HFragPixels);
  }
  
  PixelIndexTablePtr = &pbi->pixel_index_table[pbi->YPlaneFragments];
  for ( i = 0; i < ((pbi->HFragments >> 1) * pbi->VFragments); i++ ) {
    PixelIndexTablePtr[ i ] =  
      ((i / (pbi->HFragments / 2) ) * 
       (pbi->Configuration.VFragPixels * 
        (pbi->Configuration.VideoFrameWidth / 2)) );   
    PixelIndexTablePtr[ i ] += 
      ((i % (pbi->HFragments / 2) ) * 
       pbi->Configuration.HFragPixels) + pbi->YPlaneSize;
  }

  /************************************************************************/
  /* Now calculate the pixel index table for image reconstruction buffers */
  PixelIndexTablePtr = pbi->recon_pixel_index_table;
  for ( i = 0; i < pbi->YPlaneFragments; i++ ){
    PixelIndexTablePtr[ i ] = 
      ((i / pbi->HFragments) * pbi->Configuration.VFragPixels *
       pbi->Configuration.YStride);  
    PixelIndexTablePtr[ i ] += 
      ((i % pbi->HFragments) * pbi->Configuration.HFragPixels) + 
      pbi->ReconYDataOffset;
  }
   
  /* U blocks */
  PixelIndexTablePtr = &pbi->recon_pixel_index_table[pbi->YPlaneFragments];
  for ( i = 0; i < pbi->UVPlaneFragments; i++ ) {
    PixelIndexTablePtr[ i ] =  
      ((i / (pbi->HFragments / 2) ) * 
       (pbi->Configuration.VFragPixels * (pbi->Configuration.UVStride)) );   
    PixelIndexTablePtr[ i ] += 
      ((i % (pbi->HFragments / 2) ) * 
       pbi->Configuration.HFragPixels) + pbi->ReconUDataOffset;
  }
  
  /* V blocks */
  PixelIndexTablePtr = 
    &pbi->recon_pixel_index_table[pbi->YPlaneFragments + 
                                 pbi->UVPlaneFragments];

  for ( i = 0; i < pbi->UVPlaneFragments; i++ ) {
    PixelIndexTablePtr[ i ] =  
      ((i / (pbi->HFragments / 2) ) * 
       (pbi->Configuration.VFragPixels * (pbi->Configuration.UVStride)) );   
    PixelIndexTablePtr[ i ] += 
      ((i % (pbi->HFragments / 2) ) * pbi->Configuration.HFragPixels) + 
      pbi->ReconVDataOffset;
  }
}

void ClearFragmentInfo(PB_INSTANCE * pbi){

  /* free prior allocs if present */
  if(pbi->display_fragments) _ogg_free(pbi->display_fragments);
  if(pbi->pixel_index_table) _ogg_free(pbi->pixel_index_table);
  if(pbi->recon_pixel_index_table) _ogg_free(pbi->recon_pixel_index_table);
  if(pbi->FragTokenCounts) _ogg_free(pbi->FragTokenCounts);
  if(pbi->CodedBlockList) _ogg_free(pbi->CodedBlockList);
  if(pbi->FragMVect) _ogg_free(pbi->FragMVect);
  if(pbi->FragCoeffs) _ogg_free(pbi->FragCoeffs);
  if(pbi->FragCoefEOB) _ogg_free(pbi->FragCoefEOB);
  if(pbi->skipped_display_fragments) _ogg_free(pbi->skipped_display_fragments);
  if(pbi->QFragData) _ogg_free(pbi->QFragData);
  if(pbi->TokenList) _ogg_free(pbi->TokenList);
  if(pbi->FragCodingMethod) _ogg_free(pbi->FragCodingMethod);
  if(pbi->FragCoordinates) _ogg_free(pbi->FragCoordinates);

  if(pbi->FragQIndex) _ogg_free(pbi->FragQIndex);
  if(pbi->PPCoefBuffer) _ogg_free(pbi->PPCoefBuffer);
  if(pbi->FragmentVariances) _ogg_free(pbi->FragmentVariances);

  if(pbi->BlockMap) _ogg_free(pbi->BlockMap);

  if(pbi->SBCodedFlags) _ogg_free(pbi->SBCodedFlags);
  if(pbi->SBFullyFlags) _ogg_free(pbi->SBFullyFlags);
  if(pbi->MBFullyFlags) _ogg_free(pbi->MBFullyFlags);
  if(pbi->MBCodedFlags) _ogg_free(pbi->MBCodedFlags);
  
  if(pbi->_Nodes) _ogg_free(pbi->_Nodes);
  pbi->_Nodes = 0;    
  
  pbi->QFragData = 0;
  pbi->TokenList = 0;
  pbi->skipped_display_fragments = 0;
  pbi->FragCoeffs = 0;
  pbi->FragCoefEOB = 0;
  pbi->display_fragments = 0;
  pbi->pixel_index_table = 0;
  pbi->recon_pixel_index_table = 0;
  pbi->FragTokenCounts = 0;
  pbi->CodedBlockList = 0;
  pbi->FragCodingMethod = 0;
  pbi->FragMVect = 0;
  pbi->MBCodedFlags = 0;
  pbi->MBFullyFlags = 0;
  pbi->BlockMap = 0;
  
  pbi->SBCodedFlags = 0;
  pbi->SBFullyFlags = 0;
  pbi->QFragData = 0;                  
  pbi->TokenList = 0;
  pbi->skipped_display_fragments = 0;
  pbi->FragCoeffs = 0;
  pbi->FragCoefEOB = 0;
  pbi->display_fragments = 0;
  pbi->pixel_index_table = 0;
  pbi->recon_pixel_index_table = 0;
  pbi->FragTokenCounts = 0;
  pbi->CodedBlockList = 0;
  pbi->FragCodingMethod = 0;
  pbi->FragCoordinates = 0;
  pbi->FragMVect = 0;
  
  pbi->PPCoefBuffer=0;
  pbi->PPCoefBuffer=0;
  pbi->FragQIndex = 0;
  pbi->FragQIndex = 0;
  pbi->FragmentVariances= 0;
  pbi->FragmentVariances = 0 ;
}

void InitFragmentInfo(PB_INSTANCE * pbi){

  /* clear any existing info */
  ClearFragmentInfo(pbi);

  /* Perform Fragment Allocations */
  pbi->display_fragments = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->display_fragments));

  pbi->pixel_index_table = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->pixel_index_table));

  pbi->recon_pixel_index_table = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->recon_pixel_index_table));

  pbi->FragTokenCounts = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->FragTokenCounts));

  pbi->CodedBlockList = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->CodedBlockList));
    
  pbi->FragMVect = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->FragMVect));
    
  pbi->FragCoeffs = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->FragCoeffs));
    
  pbi->FragCoefEOB = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->FragCoefEOB));
    
  pbi->skipped_display_fragments = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->skipped_display_fragments));
    
  pbi->QFragData = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->QFragData) * 64);
    
  pbi->TokenList = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->TokenList) * 128);
    
  pbi->FragCodingMethod = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->FragCodingMethod));

  pbi->FragCoordinates = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->FragCoordinates));

  pbi->FragQIndex = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->FragQIndex));

  pbi->PPCoefBuffer = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->PPCoefBuffer) * 64);

  pbi->FragmentVariances = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->FragmentVariances));

  pbi->_Nodes = 
    _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->_Nodes));
        
  /* Super Block Initialization */
  pbi->SBCodedFlags =
    _ogg_malloc(pbi->SuperBlocks * sizeof(*pbi->SBCodedFlags));

  pbi->SBFullyFlags = 
    _ogg_malloc(pbi->SuperBlocks * sizeof(*pbi->SBFullyFlags));

  /* Macro Block Initialization */
  pbi->MBCodedFlags = 
    _ogg_malloc(pbi->MacroBlocks * sizeof(*pbi->MBCodedFlags));

  pbi->MBFullyFlags = 
    _ogg_malloc(pbi->MacroBlocks * sizeof(*pbi->MBFullyFlags));

  pbi->BlockMap = 
    _ogg_malloc(pbi->SuperBlocks * sizeof(*pbi->BlockMap) * 4 * 4);

}

void ClearFrameInfo(PB_INSTANCE * pbi){
  if(pbi->ThisFrameRecon )
    _ogg_free(pbi->ThisFrameRecon );
  if(pbi->GoldenFrame)
    _ogg_free(pbi->GoldenFrame);
  if(pbi->LastFrameRecon)
    _ogg_free(pbi->LastFrameRecon);
  if(pbi->PostProcessBuffer)
    _ogg_free(pbi->PostProcessBuffer);
  
  
  pbi->ThisFrameRecon = 0;
  pbi->GoldenFrame = 0;
  pbi->LastFrameRecon = 0;
  pbi->PostProcessBuffer = 0;
  
  
  pbi->ThisFrameRecon = 0;
  pbi->GoldenFrame = 0;
  pbi->LastFrameRecon = 0;
  pbi->PostProcessBuffer = 0;
  
}

void InitFrameInfo(PB_INSTANCE * pbi, unsigned int FrameSize){
  
  /* clear any existing info */
  ClearFrameInfo(pbi);

  /* allocate frames */
  pbi->ThisFrameRecon = 
    _ogg_malloc(FrameSize*sizeof(*pbi->ThisFrameRecon));
  
  pbi->GoldenFrame = 
    _ogg_malloc(FrameSize*sizeof(*pbi->GoldenFrame));
  
  pbi->LastFrameRecon = 
    _ogg_malloc(FrameSize*sizeof(*pbi->LastFrameRecon));
  
  pbi->PostProcessBuffer = 
    _ogg_malloc(FrameSize*sizeof(*pbi->PostProcessBuffer));
  
}

void InitializeFragCoordinates(PB_INSTANCE *pbi){

  ogg_uint32_t i, j;
  
  ogg_uint32_t HorizFrags = pbi->HFragments;
  ogg_uint32_t VertFrags = pbi->VFragments;
  ogg_uint32_t StartFrag = 0;
  
  /* Y */
    
  for(i = 0; i< VertFrags; i++){
    for(j = 0; j< HorizFrags; j++){
            
      ogg_uint32_t ThisFrag = i * HorizFrags + j;
      pbi->FragCoordinates[ ThisFrag ].x=j * BLOCK_HEIGHT_WIDTH;
      pbi->FragCoordinates[ ThisFrag ].y=i * BLOCK_HEIGHT_WIDTH;            
      
    }
  }
  
  /* U */
  HorizFrags >>= 1;
  VertFrags >>= 1;
  StartFrag = pbi->YPlaneFragments;

  for(i = 0; i< VertFrags; i++) {
    for(j = 0; j< HorizFrags; j++) {
      ogg_uint32_t ThisFrag = StartFrag + i * HorizFrags + j;
      pbi->FragCoordinates[ ThisFrag ].x=j * BLOCK_HEIGHT_WIDTH;
      pbi->FragCoordinates[ ThisFrag ].y=i * BLOCK_HEIGHT_WIDTH;            
      
    }
  }
  
  /* V */
  StartFrag = pbi->YPlaneFragments + pbi->UVPlaneFragments;
  for(i = 0; i< VertFrags; i++) {
    for(j = 0; j< HorizFrags; j++) {
      ogg_uint32_t ThisFrag = StartFrag + i * HorizFrags + j;
      pbi->FragCoordinates[ ThisFrag ].x=j * BLOCK_HEIGHT_WIDTH;
      pbi->FragCoordinates[ ThisFrag ].y=i * BLOCK_HEIGHT_WIDTH;            
      
    }
  }
}

void InitFrameDetails(PB_INSTANCE *pbi){
  int FrameSize;
  
  /*pbi->PostProcessingLevel = 0;
    pbi->PostProcessingLevel = 4;
    pbi->PostProcessingLevel = 5;*/
  pbi->PostProcessingLevel = 6;

    /* Set the frame size etc. */                

  pbi->YPlaneSize = pbi->Configuration.VideoFrameWidth * 
    pbi->Configuration.VideoFrameHeight; 
  pbi->UVPlaneSize = pbi->YPlaneSize / 4;  
  pbi->HFragments = pbi->Configuration.VideoFrameWidth / 
    pbi->Configuration.HFragPixels;
  pbi->VFragments = pbi->Configuration.VideoFrameHeight / 
    pbi->Configuration.VFragPixels;
  pbi->UnitFragments = ((pbi->VFragments * pbi->HFragments)*3)/2;
  pbi->YPlaneFragments = pbi->HFragments * pbi->VFragments;
  pbi->UVPlaneFragments = pbi->YPlaneFragments / 4;

  pbi->Configuration.YStride = 
    (pbi->Configuration.VideoFrameWidth + STRIDE_EXTRA);
  pbi->Configuration.UVStride = pbi->Configuration.YStride / 2;
  pbi->ReconYPlaneSize = pbi->Configuration.YStride * 
    (pbi->Configuration.VideoFrameHeight + STRIDE_EXTRA);
  pbi->ReconUVPlaneSize = pbi->ReconYPlaneSize / 4;
  FrameSize = pbi->ReconYPlaneSize + 2 * pbi->ReconUVPlaneSize;
  
  pbi->YDataOffset = 0;
  pbi->UDataOffset = pbi->YPlaneSize;
  pbi->VDataOffset = pbi->YPlaneSize + pbi->UVPlaneSize;
  pbi->ReconYDataOffset = 
    (pbi->Configuration.YStride * UMV_BORDER) + UMV_BORDER;
  pbi->ReconUDataOffset = pbi->ReconYPlaneSize + 
    (pbi->Configuration.UVStride * (UMV_BORDER/2)) + (UMV_BORDER/2);
  pbi->ReconVDataOffset = pbi->ReconYPlaneSize + pbi->ReconUVPlaneSize + 
    (pbi->Configuration.UVStride * (UMV_BORDER/2)) + (UMV_BORDER/2);
  
  /* Image dimensions in Super-Blocks */
  pbi->YSBRows = (pbi->Configuration.VideoFrameHeight/32)  + 
    ( pbi->Configuration.VideoFrameHeight%32 ? 1 : 0 );
  pbi->YSBCols = (pbi->Configuration.VideoFrameWidth/32)  + 
    ( pbi->Configuration.VideoFrameWidth%32 ? 1 : 0 );
  pbi->UVSBRows = ((pbi->Configuration.VideoFrameHeight/2)/32)  + 
    ( (pbi->Configuration.VideoFrameHeight/2)%32 ? 1 : 0 );
  pbi->UVSBCols = ((pbi->Configuration.VideoFrameWidth/2)/32)  + 
    ( (pbi->Configuration.VideoFrameWidth/2)%32 ? 1 : 0 );
  
  /* Super-Blocks per component */
  pbi->YSuperBlocks = pbi->YSBRows * pbi->YSBCols;
  pbi->UVSuperBlocks = pbi->UVSBRows * pbi->UVSBCols;
  pbi->SuperBlocks = pbi->YSuperBlocks+2*pbi->UVSuperBlocks;
  
  /* Useful externals */
  pbi->YMacroBlocks = ((pbi->VFragments+1)/2)*((pbi->HFragments+1)/2);	
  pbi->UVMacroBlocks = ((pbi->VFragments/2+1)/2)*((pbi->HFragments/2+1)/2);
  pbi->MacroBlocks = pbi->YMacroBlocks+2*pbi->UVMacroBlocks;

  InitFragmentInfo(pbi);
  InitFrameInfo(pbi, FrameSize);
  InitializeFragCoordinates(pbi);

  /* Configure mapping between quad-tree and fragments */
  CreateBlockMapping ( pbi->BlockMap, pbi->YSuperBlocks, 
                       pbi->UVSuperBlocks, pbi->HFragments, pbi->VFragments);
    
  /* Re-initialise the pixel index table. */

  CalcPixelIndexTable( pbi );

}

void InitialiseConfiguration(PB_INSTANCE *pbi){  
    pbi->Configuration.HFragPixels = 8;
    pbi->Configuration.VFragPixels = 8;
} 

<p><p><p>1.1                  theora/lib/pb.c

Index: pb.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: pb.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <stdlib.h>
#include <ogg/ogg.h>
#include "encoder_internal.h"

void ClearTmpBuffers(PB_INSTANCE * pbi){

  if(pbi->ReconDataBuffer)
    _ogg_free(pbi->ReconDataBuffer);
  if(pbi->DequantBuffer)
    _ogg_free(pbi->DequantBuffer);
  if(pbi->TmpDataBuffer)
    _ogg_free(pbi->TmpDataBuffer);
  if(pbi->TmpReconBuffer)
    _ogg_free(pbi->TmpReconBuffer);
  if(pbi->dequant_Y_coeffs)
    _ogg_free(pbi->dequant_Y_coeffs);
  if(pbi->dequant_UV_coeffs)
    _ogg_free(pbi->dequant_UV_coeffs);
  if(pbi->dequant_Inter_coeffs)
    _ogg_free(pbi->dequant_Inter_coeffs);
  if(pbi->ScaleBuffer)
    _ogg_free(pbi->ScaleBuffer);
  if(pbi->dequant_InterUV_coeffs)
    _ogg_free(pbi->dequant_InterUV_coeffs);
  

  pbi->ReconDataBuffer=0;
  pbi->DequantBuffer = 0;
  pbi->TmpDataBuffer = 0;
  pbi->TmpReconBuffer = 0;
  pbi->dequant_Y_coeffs = 0;
  pbi->dequant_UV_coeffs = 0;
  pbi->dequant_InterUV_coeffs = 0;
  pbi->dequant_Inter_coeffs = 0;
  pbi->ScaleBuffer = 0;

}

void InitTmpBuffers(PB_INSTANCE * pbi){
  
  /* clear any existing info */
  ClearTmpBuffers(pbi);
  
  /* Adjust the position of all of our temporary */
  pbi->ReconDataBuffer      = 
    _ogg_malloc(64*sizeof(*pbi->ReconDataBuffer));
  
  pbi->DequantBuffer        = 
    _ogg_malloc(64 * sizeof(*pbi->DequantBuffer));
  
  pbi->TmpDataBuffer        = 
    _ogg_malloc(64 * sizeof(*pbi->TmpDataBuffer));
  
  pbi->TmpReconBuffer       = 
    _ogg_malloc(64 * sizeof(*pbi->TmpReconBuffer));
  
  pbi->dequant_Y_coeffs     = 
    _ogg_malloc(64 * sizeof(*pbi->dequant_Y_coeffs));
  
  pbi->dequant_UV_coeffs    = 
    _ogg_malloc(64 * sizeof(*pbi->dequant_UV_coeffs));
  
  pbi->dequant_Inter_coeffs = 
    _ogg_malloc(64 * sizeof(*pbi->dequant_Inter_coeffs));
  
  pbi->dequant_InterUV_coeffs = 
    _ogg_malloc(64 * sizeof(*pbi->dequant_InterUV_coeffs));
  
}

void ClearPBInstance(PB_INSTANCE *pbi){
  if(pbi){
    ClearTmpBuffers(pbi);
  }
}

void InitPBInstance(PB_INSTANCE *pbi){
  CONFIG_TYPE ConfigurationInit = {
    0,0,0,0,
    8,8,
  };
  
  /* initialize whole structure to 0 */
  memset(pbi, 0, sizeof(*pbi));
  
  memcpy(&pbi->Configuration,&ConfigurationInit, sizeof(pbi->Configuration));
  
  InitTmpBuffers(pbi);
  
  /* variables needing initialization (not being set to 0) */
  
  pbi->ModifierPointer[0] = &pbi->Modifier[0][255];
  pbi->ModifierPointer[1] = &pbi->Modifier[1][255];
  pbi->ModifierPointer[2] = &pbi->Modifier[2][255];
  pbi->ModifierPointer[3] = &pbi->Modifier[3][255];
  
  pbi->DecoderErrorCode = 0;
  pbi->KeyFrameType = DCT_KEY_FRAME;
  pbi->FramesHaveBeenSkipped = 0;
  pbi->SkipYUVtoRGB = 0;
  pbi->OutputRGB = 0;
}

<p><p>1.1                  theora/lib/pp.h

Index: pp.h
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: pp.h,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

/* Constants. */
#define INTERNAL_BLOCK_HEIGHT   8
#define INTERNAL_BLOCK_WIDTH    8

<p>/* NEW Line search values. */ 
#define UP      0
#define DOWN    1
#define LEFT    2
#define RIGHT   3

#define FIRST_ROW           0
#define NOT_EDGE_ROW        1
#define LAST_ROW            2      

#define YDIFF_CB_ROWS                   (INTERNAL_BLOCK_HEIGHT * 3)
#define CHLOCALS_CB_ROWS                (INTERNAL_BLOCK_HEIGHT * 3)
#define PMAP_CB_ROWS                    (INTERNAL_BLOCK_HEIGHT * 3)
#define PSCORE_CB_ROWS                  (INTERNAL_BLOCK_HEIGHT * 4)

// Status values in block coding map
#define CANDIDATE_BLOCK_LOW                     -2
#define CANDIDATE_BLOCK                         -1
#define BLOCK_NOT_CODED                         0
#define BLOCK_CODED_BAR                         3       
#define BLOCK_CODED_SGC                         4       
#define BLOCK_CODED_LOW                         4       
#define BLOCK_CODED                             5       

#define MAX_PREV_FRAMES             16
#define MAX_SEARCH_LINE_LEN                     7   

<p><p><p>1.1                  theora/lib/quant.c

Index: quant.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function:
  last mod: $Id: quant.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <ogg/ogg.h>
#include "encoder_internal.h"
#include "quant_lookup.h"

void InitQTables( PB_INSTANCE *pbi ){
  memcpy ( pbi->QThreshTable, QThreshTableV1, sizeof( pbi->QThreshTable ) );
}

void BuildQuantIndex_Generic(PB_INSTANCE *pbi){
  ogg_int32_t i,j;
  
  /* invert the dequant index into the quant index */
  for ( i = 0; i < BLOCK_SIZE; i++ ){	
    j = dequant_index[i];
    pbi->quant_index[j] = i;
  }
}

void init_quantizer ( CP_INSTANCE *cpi, 
                      ogg_uint32_t scale_factor, 
                      unsigned char QIndex ){
    int i;                 
    double ZBinFactor;
    double RoundingFactor;
    
    double temp_fp_quant_coeffs;
    double temp_fp_quant_round;
    double temp_fp_ZeroBinSize;
    PB_INSTANCE *pbi = &cpi->pb;

    Q_LIST_ENTRY * Inter_coeffs;	 
    Q_LIST_ENTRY * Y_coeffs;	 
    Q_LIST_ENTRY * UV_coeffs;	 
    Q_LIST_ENTRY * DcScaleFactorTable;
    Q_LIST_ENTRY * UVDcScaleFactorTable;

    /* Notes on setup of quantisers.  The initial multiplication by
     the scale factor is done in the ogg_int32_t domain to insure that the
     precision in the quantiser is the same as in the inverse
     quantiser where all calculations are integer.  The "<< 2" is a
     normalisation factor for the forward DCT transform. */

    /* New version rounding and ZB characteristics. */
    Inter_coeffs = Inter_coeffsV1;
    Y_coeffs = Y_coeffsV1;
    UV_coeffs = UV_coeffsV1;
    DcScaleFactorTable = DcScaleFactorTableV1;
    UVDcScaleFactorTable = DcScaleFactorTableV1;
    ZBinFactor = 0.9;
    
    switch(cpi->Sharpness){
    case 0:
      ZBinFactor = 0.65;
      if ( scale_factor <= 50 )
        RoundingFactor = 0.499;
      else
        RoundingFactor = 0.46;
      break;
    case 1:
      ZBinFactor = 0.75;
      if ( scale_factor <= 50 )
        RoundingFactor = 0.476;
      else
        RoundingFactor = 0.400;
      break;
      
    default:
      ZBinFactor = 0.9;
      if ( scale_factor <= 50 )
        RoundingFactor = 0.476;
      else
        RoundingFactor = 0.333;
      break;
    }
    
    /* Use fixed multiplier for intra Y DC */
    temp_fp_quant_coeffs = 
      (((ogg_uint32_t)(DcScaleFactorTable[QIndex] * Y_coeffs[0])/100) << 2);
    if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2 )
      temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;
    
    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
    pbi->fp_quant_Y_round[0]	= (ogg_int32_t) (0.5 + temp_fp_quant_round);
    
    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
    pbi->fp_ZeroBinSize_Y[0]	= (ogg_int32_t) (0.5 + temp_fp_ZeroBinSize);
    
    temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
    pbi->fp_quant_Y_coeffs[0]	= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
    
    /* Intra UV */
    temp_fp_quant_coeffs = 
      (((ogg_uint32_t)(UVDcScaleFactorTable[QIndex] * UV_coeffs[0])/100) << 2);
    if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2)
      temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;
    
    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
    pbi->fp_quant_UV_round[0]	= (0.5 + temp_fp_quant_round);
    
    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
    pbi->fp_ZeroBinSize_UV[0]	= (0.5 + temp_fp_ZeroBinSize);
    
    temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
    pbi->fp_quant_UV_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
    
    /* Inter Y */
    temp_fp_quant_coeffs = 
      (((ogg_uint32_t)(DcScaleFactorTable[QIndex] * Inter_coeffs[0])/100) << 2);
    if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)
      temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;
    
    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
    pbi->fp_quant_Inter_round[0]= (0.5 + temp_fp_quant_round);    
    
    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
    pbi->fp_ZeroBinSize_Inter[0]= (0.5 + temp_fp_ZeroBinSize);
    
    temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
    pbi->fp_quant_Inter_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
    
    // Inter UV
    temp_fp_quant_coeffs = 
      (((ogg_uint32_t)(UVDcScaleFactorTable[QIndex] * Inter_coeffs[0])/100) << 2);
    if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)
      temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;
    
    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
    pbi->fp_quant_InterUV_round[0]= (0.5 + temp_fp_quant_round);    
    
    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
    pbi->fp_ZeroBinSize_InterUV[0]= (0.5 + temp_fp_ZeroBinSize);
    
    temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
    pbi->fp_quant_InterUV_coeffs[0]= 
      (0.5 + SHIFT16 * temp_fp_quant_coeffs);
    
    for ( i = 1; i < 64; i++ ){
      /* now scale coefficients by required compression factor */
      /* Intra Y */
      temp_fp_quant_coeffs =  
        (((ogg_uint32_t)(scale_factor * Y_coeffs[i]) / 100 ) << 2 );
      if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY) )
        temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);
      
      temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
      pbi->fp_quant_Y_round[i]	= (0.5 + temp_fp_quant_round);
      
      temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
      pbi->fp_ZeroBinSize_Y[i]	= (0.5 + temp_fp_ZeroBinSize);
      
      temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
      pbi->fp_quant_Y_coeffs[i]	= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
      
      /* Intra UV */
      temp_fp_quant_coeffs =  
        (((ogg_uint32_t)(scale_factor * UV_coeffs[i]) / 100 ) << 2 );
      if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY))
        temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);
      
      temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
      pbi->fp_quant_UV_round[i]	= (0.5 + temp_fp_quant_round);

      temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
      pbi->fp_ZeroBinSize_UV[i]	= (0.5 + temp_fp_ZeroBinSize);

      temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
      pbi->fp_quant_UV_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);

      /* Inter Y */
      temp_fp_quant_coeffs =  
        (((ogg_uint32_t)(scale_factor * Inter_coeffs[i]) / 100 ) << 2 );
      if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )
        temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);
      
      temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;    
      pbi->fp_quant_Inter_round[i]= (0.5 + temp_fp_quant_round);    
      
      temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
      pbi->fp_ZeroBinSize_Inter[i]= (0.5 + temp_fp_ZeroBinSize);
      
      temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
      pbi->fp_quant_Inter_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
      
      /* Inter UV */
      temp_fp_quant_coeffs = 
        (((ogg_uint32_t)(scale_factor * Inter_coeffs[i]) / 100 ) << 2 );
      if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )
        temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);
      
      temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;    
      pbi->fp_quant_InterUV_round[i]= (0.5 + temp_fp_quant_round);    
        
      temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
      pbi->fp_ZeroBinSize_InterUV[i]= (0.5 + temp_fp_ZeroBinSize);

      temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
      pbi->fp_quant_InterUV_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
        
    }

    pbi->fquant_coeffs = pbi->fp_quant_Y_coeffs;

}

void select_Y_quantiser ( PB_INSTANCE *pbi ){	
  pbi->fquant_coeffs = pbi->fp_quant_Y_coeffs;
  pbi->fquant_round = pbi->fp_quant_Y_round;
  pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Y;
}

void select_Inter_quantiser ( PB_INSTANCE *pbi ){	
  pbi->fquant_coeffs = pbi->fp_quant_Inter_coeffs;
  pbi->fquant_round = pbi->fp_quant_Inter_round;
  pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Inter;
}

void select_UV_quantiser ( PB_INSTANCE *pbi ){	
  pbi->fquant_coeffs = pbi->fp_quant_UV_coeffs;
  pbi->fquant_round = pbi->fp_quant_UV_round;
  pbi->fquant_ZbSize = pbi->fp_quant_UV_round;
}

void select_InterUV_quantiser ( PB_INSTANCE *pbi ){	
  pbi->fquant_coeffs = pbi->fp_quant_InterUV_coeffs;
  pbi->fquant_round = pbi->fp_quant_InterUV_round;
  pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_InterUV;
}

void quantize( PB_INSTANCE *pbi, 
               ogg_int16_t * DCT_block, 
               Q_LIST_ENTRY * quantized_list){
  ogg_uint32_t   	i;              /*	Row index */
  Q_LIST_ENTRY  val;            /* Quantised value. */
  
  ogg_int32_t * FquantRoundPtr = pbi->fquant_round;
  ogg_int32_t * FquantCoeffsPtr = pbi->fquant_coeffs;
  ogg_int32_t * FquantZBinSizePtr = pbi->fquant_ZbSize;
  ogg_int16_t * DCT_blockPtr = DCT_block;
  ogg_uint32_t * QIndexPtr = (ogg_uint32_t *)pbi->quant_index;
  ogg_int32_t temp;
  int x = -7 >> 1;
  
  /* Set the quantized_list to default to 0 */
  memset( quantized_list, 0, 64 * sizeof(Q_LIST_ENTRY) );
  
  /* Note that we add half divisor to effect rounding on positive number */
  for( i = 0; i < pbi->Configuration.VFragPixels; i++) {
    /* Column 0  */
    if ( DCT_blockPtr[0] >= FquantZBinSizePtr[0] ) {
      temp = FquantCoeffsPtr[0] * ( DCT_blockPtr[0] + FquantRoundPtr[0] ) ;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[0]] = ( val > 511 ) ? 511 : val;
    } else if ( DCT_blockPtr[0] <= -FquantZBinSizePtr[0] ) {
      temp = FquantCoeffsPtr[0] * 
        ( DCT_blockPtr[0] - FquantRoundPtr[0] ) + MIN16;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[0]] = ( val < -511 ) ? -511 : val;
    }

    /* Column 1 */
    if ( DCT_blockPtr[1] >= FquantZBinSizePtr[1] ) {
      temp = FquantCoeffsPtr[1] * 
        ( DCT_blockPtr[1] + FquantRoundPtr[1] ) ;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[1]] = ( val > 511 ) ? 511 : val;
    } else if ( DCT_blockPtr[1] <= -FquantZBinSizePtr[1] ) {
      temp = FquantCoeffsPtr[1] * 
        ( DCT_blockPtr[1] - FquantRoundPtr[1] ) + MIN16;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[1]] = ( val < -511 ) ? -511 : val;
    }

    /* Column 2 */
    if ( DCT_blockPtr[2] >= FquantZBinSizePtr[2] ) {
      temp = FquantCoeffsPtr[2] * 
        ( DCT_blockPtr[2] + FquantRoundPtr[2] ) ;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[2]] = ( val > 511 ) ? 511 : val;
    } else if ( DCT_blockPtr[2] <= -FquantZBinSizePtr[2] ) {
      temp = FquantCoeffsPtr[2] * 
        ( DCT_blockPtr[2] - FquantRoundPtr[2] ) + MIN16;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[2]] = ( val < -511 ) ? -511 : val;
    }
    
    /* Column 3 */
    if ( DCT_blockPtr[3] >= FquantZBinSizePtr[3] ) {
      temp = FquantCoeffsPtr[3] * 
        ( DCT_blockPtr[3] + FquantRoundPtr[3] ) ;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[3]] = ( val > 511 ) ? 511 : val;
    } else if ( DCT_blockPtr[3] <= -FquantZBinSizePtr[3] ) {
      temp = FquantCoeffsPtr[3] * 
        ( DCT_blockPtr[3] - FquantRoundPtr[3] ) + MIN16;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[3]] = ( val < -511 ) ? -511 : val;
    }
    
    /* Column 4 */
    if ( DCT_blockPtr[4] >= FquantZBinSizePtr[4] ) {
      temp = FquantCoeffsPtr[4] * 
        ( DCT_blockPtr[4] + FquantRoundPtr[4] ) ;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[4]] = ( val > 511 ) ? 511 : val;
    } else if ( DCT_blockPtr[4] <= -FquantZBinSizePtr[4] ) {
      temp = FquantCoeffsPtr[4] * 
        ( DCT_blockPtr[4] - FquantRoundPtr[4] ) + MIN16;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[4]] = ( val < -511 ) ? -511 : val;
    }

    /* Column 5 */
    if ( DCT_blockPtr[5] >= FquantZBinSizePtr[5] ) {
      temp = FquantCoeffsPtr[5] * 
        ( DCT_blockPtr[5] + FquantRoundPtr[5] ) ;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[5]] = ( val > 511 ) ? 511 : val;
    } else if ( DCT_blockPtr[5] <= -FquantZBinSizePtr[5] ) {
      temp = FquantCoeffsPtr[5] * 
        ( DCT_blockPtr[5] - FquantRoundPtr[5] ) + MIN16;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[5]] = ( val < -511 ) ? -511 : val;
    }
    
    /* Column 6 */
    if ( DCT_blockPtr[6] >= FquantZBinSizePtr[6] ) {
      temp = FquantCoeffsPtr[6] * 
        ( DCT_blockPtr[6] + FquantRoundPtr[6] ) ;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[6]] = ( val > 511 ) ? 511 : val;
    } else if ( DCT_blockPtr[6] <= -FquantZBinSizePtr[6] ) {
      temp = FquantCoeffsPtr[6] * 
        ( DCT_blockPtr[6] - FquantRoundPtr[6] ) + MIN16;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[6]] = ( val < -511 ) ? -511 : val;
    }
    
    /* Column 7 */
    if ( DCT_blockPtr[7] >= FquantZBinSizePtr[7] ) {
      temp = FquantCoeffsPtr[7] * 
        ( DCT_blockPtr[7] + FquantRoundPtr[7] ) ;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[7]] = ( val > 511 ) ? 511 : val;
    } else if ( DCT_blockPtr[7] <= -FquantZBinSizePtr[7] ) {
      temp = FquantCoeffsPtr[7] * 
        ( DCT_blockPtr[7] - FquantRoundPtr[7] ) + MIN16;
      val = (Q_LIST_ENTRY) (temp>>16);
      quantized_list[QIndexPtr[7]] = ( val < -511 ) ? -511 : val;
    }
    
    FquantRoundPtr += 8;
    FquantCoeffsPtr += 8;
    FquantZBinSizePtr += 8;
    DCT_blockPtr += 8;
    QIndexPtr += 8;
  }
}

void init_dequantizer ( PB_INSTANCE *pbi, 
                        ogg_uint32_t scale_factor, 
                        unsigned char  QIndex ){
  int i, j;
  
  Q_LIST_ENTRY * Inter_coeffs;	 
  Q_LIST_ENTRY * Y_coeffs;	 
  Q_LIST_ENTRY * UV_coeffs;	 
  Q_LIST_ENTRY * DcScaleFactorTable;
  Q_LIST_ENTRY * UVDcScaleFactorTable;
  
  Inter_coeffs = Inter_coeffsV1;
  Y_coeffs = Y_coeffsV1;
  UV_coeffs = UV_coeffsV1;
  DcScaleFactorTable = DcScaleFactorTableV1;
  UVDcScaleFactorTable = DcScaleFactorTableV1;
  
  /* invert the dequant index into the quant index
     the dxer has a different order than the cxer. */
  BuildQuantIndex_Generic(pbi);
  
  /* Reorder dequantisation coefficients into dct zigzag order. */
  for ( i = 0; i < BLOCK_SIZE; i++ ) {	
    j = pbi->quant_index[i];
    pbi->dequant_Y_coeffs[j] = Y_coeffs[i];
  }
  for ( i = 0; i < BLOCK_SIZE; i++ ){	
    j = pbi->quant_index[i];
    pbi->dequant_Inter_coeffs[j] = Inter_coeffs[i];
  }
  for ( i = 0; i < BLOCK_SIZE; i++ ){	
    j = pbi->quant_index[i];
    pbi->dequant_UV_coeffs[j] = UV_coeffs[i];
  }
  for ( i = 0; i < BLOCK_SIZE; i++ ){	
    j = pbi->quant_index[i];
    pbi->dequant_InterUV_coeffs[j] = Inter_coeffs[i];
  }
  
  /* Intra Y */
  pbi->dequant_Y_coeffs[0] = 
    ((DcScaleFactorTable[QIndex] * pbi->dequant_Y_coeffs[0])/100);
  if ( pbi->dequant_Y_coeffs[0] < MIN_DEQUANT_VAL * 2 )
    pbi->dequant_Y_coeffs[0] = MIN_DEQUANT_VAL * 2;
  pbi->dequant_Y_coeffs[0] = 
    pbi->dequant_Y_coeffs[0] << IDCT_SCALE_FACTOR;

  /* Intra UV */
  pbi->dequant_UV_coeffs[0] = 
    ((UVDcScaleFactorTable[QIndex] * pbi->dequant_UV_coeffs[0])/100);
  if ( pbi->dequant_UV_coeffs[0] < MIN_DEQUANT_VAL * 2 )
    pbi->dequant_UV_coeffs[0] = MIN_DEQUANT_VAL * 2;
  pbi->dequant_UV_coeffs[0] = 
    pbi->dequant_UV_coeffs[0] << IDCT_SCALE_FACTOR;
  
  /* Inter Y */
  pbi->dequant_Inter_coeffs[0] = 
    ((DcScaleFactorTable[QIndex] * pbi->dequant_Inter_coeffs[0])/100);
  if ( pbi->dequant_Inter_coeffs[0] < MIN_DEQUANT_VAL * 4 )
    pbi->dequant_Inter_coeffs[0] = MIN_DEQUANT_VAL * 4;
  pbi->dequant_Inter_coeffs[0] = 
    pbi->dequant_Inter_coeffs[0] << IDCT_SCALE_FACTOR;
  
  /* Inter UV */
  pbi->dequant_InterUV_coeffs[0] = 
    ((UVDcScaleFactorTable[QIndex] * pbi->dequant_InterUV_coeffs[0])/100);
  if ( pbi->dequant_InterUV_coeffs[0] < MIN_DEQUANT_VAL * 4 )
    pbi->dequant_InterUV_coeffs[0] = MIN_DEQUANT_VAL * 4;
  pbi->dequant_InterUV_coeffs[0] = 
    pbi->dequant_InterUV_coeffs[0] << IDCT_SCALE_FACTOR;
  
  for ( i = 1; i < 64; i++ ){	
    /* now scale coefficients by required compression factor */
    pbi->dequant_Y_coeffs[i] = 
      (( scale_factor * pbi->dequant_Y_coeffs[i] ) / 100);
    if ( pbi->dequant_Y_coeffs[i] < MIN_DEQUANT_VAL )
      pbi->dequant_Y_coeffs[i] = MIN_DEQUANT_VAL;
    pbi->dequant_Y_coeffs[i] = 
      pbi->dequant_Y_coeffs[i] << IDCT_SCALE_FACTOR;

    pbi->dequant_UV_coeffs[i] = 
      (( scale_factor * pbi->dequant_UV_coeffs[i] ) / 100);
    if ( pbi->dequant_UV_coeffs[i] < MIN_DEQUANT_VAL )
      pbi->dequant_UV_coeffs[i] = MIN_DEQUANT_VAL;
    pbi->dequant_UV_coeffs[i] = 
      pbi->dequant_UV_coeffs[i] << IDCT_SCALE_FACTOR;
    
    pbi->dequant_Inter_coeffs[i] = 
      (( scale_factor * pbi->dequant_Inter_coeffs[i] ) / 100);
    if ( pbi->dequant_Inter_coeffs[i] < (MIN_DEQUANT_VAL * 2) )
      pbi->dequant_Inter_coeffs[i] = MIN_DEQUANT_VAL * 2;
    pbi->dequant_Inter_coeffs[i] = 
      pbi->dequant_Inter_coeffs[i] << IDCT_SCALE_FACTOR;
    
    pbi->dequant_InterUV_coeffs[i] = 
      (( scale_factor * pbi->dequant_InterUV_coeffs[i] ) / 100);
    if ( pbi->dequant_InterUV_coeffs[i] < (MIN_DEQUANT_VAL * 2) )
      pbi->dequant_InterUV_coeffs[i] = MIN_DEQUANT_VAL * 2;
    pbi->dequant_InterUV_coeffs[i] = 
      pbi->dequant_InterUV_coeffs[i] << IDCT_SCALE_FACTOR;
  }
  
  pbi->dequant_coeffs = pbi->dequant_Y_coeffs;
}

void UpdateQ( PB_INSTANCE *pbi, ogg_uint32_t NewQ ){  
  ogg_uint32_t qscale;
  
  /* Do bounds checking and convert to a float. */
  qscale = NewQ; 
  if ( qscale < pbi->QThreshTable[Q_TABLE_SIZE-1] )
    qscale = pbi->QThreshTable[Q_TABLE_SIZE-1];
  else if ( qscale > pbi->QThreshTable[0] )
    qscale = pbi->QThreshTable[0];       
  
  /* Set the inter/intra descision control variables. */
  pbi->FrameQIndex = Q_TABLE_SIZE - 1;
  while ( (ogg_int32_t) pbi->FrameQIndex >= 0 ) {
    if ( (pbi->FrameQIndex == 0) || 
         ( pbi->QThreshTable[pbi->FrameQIndex] >= NewQ) )
      break;
    pbi->FrameQIndex --;
  }
  
  /* Re-initialise the q tables for forward and reverse transforms. */
  init_dequantizer ( pbi, qscale, (unsigned char) pbi->FrameQIndex );
}

void UpdateQC( CP_INSTANCE *cpi, ogg_uint32_t NewQ ){  
  ogg_uint32_t qscale;
  PB_INSTANCE *pbi = &cpi->pb;

  /* Do bounds checking and convert to a float.  */
  qscale = NewQ; 
  if ( qscale < pbi->QThreshTable[Q_TABLE_SIZE-1] )
    qscale = pbi->QThreshTable[Q_TABLE_SIZE-1];
  else if ( qscale > pbi->QThreshTable[0] )
    qscale = pbi->QThreshTable[0];       
  
  /* Set the inter/intra descision control variables. */
  pbi->FrameQIndex = Q_TABLE_SIZE - 1;
  while ((ogg_int32_t) pbi->FrameQIndex >= 0 ) {
    if ( (pbi->FrameQIndex == 0) || 
         ( pbi->QThreshTable[pbi->FrameQIndex] >= NewQ) )
      break;
    pbi->FrameQIndex --;
  }
  
  /* Re-initialise the q tables for forward and reverse transforms. */
  init_quantizer ( cpi, qscale, (unsigned char) pbi->FrameQIndex );
  init_dequantizer ( pbi, qscale, (unsigned char) pbi->FrameQIndex );
}

<p><p><p>1.1                  theora/lib/quant_lookup.h

Index: quant_lookup.h
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function:
  last mod: $Id: quant_lookup.h,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#define MIN16 ((1<<16)-1)
#define SHIFT16 (1<<16)

#define MIN_LEGAL_QUANT_ENTRY 8  
#define MIN_DEQUANT_VAL       2
#define IDCT_SCALE_FACTOR     2 /* Shift left bits to improve IDCT precision */
#define OLD_SCHEME            1

tatic ogg_uint32_t QThreshTableV1[Q_TABLE_SIZE] = { 
  500,  450,  400,  370,  340,  310, 285, 265,
  245,  225,  210,  195,  185,  180, 170, 160, 
  150,  145,  135,  130,  125,  115, 110, 107,
  100,   96,   93,   89,   85,   82,  75,  74,
  70,   68,   64,   60,   57,   56,  52,  50,  
  49,   45,   44,   43,   40,   38,  37,  35,  
  33,   32,   30,   29,   28,   25,  24,  22,
  21,   19,   18,   17,   15,   13,  12,  10 
};

<p>static Q_LIST_ENTRY DcScaleFactorTableV1[ Q_TABLE_SIZE ] = { 
  220, 200, 190, 180, 170, 170, 160, 160,
  150, 150, 140, 140, 130, 130, 120, 120,
  110, 110, 100, 100, 90,  90,  90,  80,
  80,  80,  70,  70,  70,  60,  60,  60,
  60,  50,  50,  50,  50,  40,  40,  40,
  40,  40,  30,  30,  30,  30,  30,  30,
  30,  20,  20,  20,  20,  20,  20,  20,
  20,  10,  10,  10,  10,  10,  10,  10 
};

tatic ogg_uint32_t DcQuantScaleV1[ Q_TABLE_SIZE ] = { 
  22, 20, 19, 18, 17, 17, 16, 16,
  15, 15, 14, 14, 13, 13, 12, 12,
  11, 11, 10, 10, 9,  9,  9,  8,
  8,  8,  7,  7,  7,  6,  6,  6,
  6,  5,  5,  5,  5,  4,  4,  4,
  4,  4,  3,  3,  3,  3,  3,  3,
  3,  2,  2,  2,  2,  2,  2,  2,
  2,  1,  1,  1,  1,  1,  1,  1 
};

<p>static Q_LIST_ENTRY Y_coeffsV1[64] ={
  16,  11,  10,  16,  24,  40,  51,  61,
  12,  12,  14,  19,  26,  58,  60,  55, 
  14,  13,  16,  24,  40,  57,  69,  56, 
  14,  17,  22,  29,  51,  87,  80,  62, 
  18,  22,  37,  58,  68, 109, 103,  77, 
  24,  35,  55,  64,  81, 104, 113,  92, 
  49,  64,  78,  87, 103, 121, 120, 101, 
  72,  92,  95,  98, 112, 100, 103,  99
};

tatic Q_LIST_ENTRY UV_coeffsV1[64] ={	
  17,	18,	24,	47,	99,	99,	99,	99,
  18,	21,	26,	66,	99,	99,	99,	99,
  24,	26,	56,	99,	99,	99,	99,	99,
  47,	66,	99,	99,	99,	99,	99,	99,
  99,	99,	99,	99,	99,	99,	99,	99,
  99,	99,	99,	99,	99,	99,	99,	99,
  99,	99,	99,	99,	99,	99,	99,	99,
  99,	99,	99,	99,	99,	99,	99,	99
};

/* Different matrices for different encoder versions */
static Q_LIST_ENTRY Inter_coeffsV1[64] ={
  16,  16,  16,  20,  24,  28,  32,  40,
  16,  16,  20,  24,  28,  32,  40,  48, 
  16,  20,  24,  28,  32,  40,  48,  64, 
  20,  24,  28,  32,  40,  48,  64,  64, 
  24,  28,  32,  40,  48,  64,  64,  64, 
  28,  32,  40,  48,  64,  64,  64,  96, 
  32,  40,  48,  64,  64,  64,  96,  128,
  40,  48,  64,  64,  64,  96,  128, 128
};

tatic ogg_uint32_t dequant_index[64] = {	
  0,  1,  8,  16,  9,  2,  3, 10,
  17, 24, 32, 25, 18, 11,  4,  5,
  12, 19, 26, 33, 40, 48, 41, 34,
  27, 20, 13,  6,  7, 14, 21, 28,
  35, 42, 49, 56, 57, 50, 43, 36, 
  29, 22, 15, 23, 30, 37, 44, 51,
  58, 59, 52, 45, 38, 31, 39, 46,
  53, 60, 61, 54, 47, 55, 62, 63
};

<p><p><p>1.1                  theora/lib/reconstruct.c

Index: reconstruct.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: reconstruct.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <ogg/ogg.h>
#include "encoder_internal.h"

<p>void SatUnsigned8( unsigned char * ResultPtr, ogg_int16_t * DataBlock, 
                   ogg_uint32_t ResultLineStep, ogg_uint32_t DataLineStep ) {
  int  i;
       
  for ( i = 0; i < BLOCK_HEIGHT_WIDTH; i++ ){
    ResultPtr[0] = clamp255(DataBlock[0]);
    ResultPtr[1] = clamp255(DataBlock[1]);
    ResultPtr[2] = clamp255(DataBlock[2]);
    ResultPtr[3] = clamp255(DataBlock[3]);
    ResultPtr[4] = clamp255(DataBlock[4]);
    ResultPtr[5] = clamp255(DataBlock[5]);
    ResultPtr[6] = clamp255(DataBlock[6]);
    ResultPtr[7] = clamp255(DataBlock[7]);
    
    DataBlock += DataLineStep;
    ResultPtr += ResultLineStep;
  }
}

void ReconIntra( PB_INSTANCE *pbi, unsigned char * ReconPtr, 
                 ogg_uint16_t * ChangePtr, ogg_uint32_t LineStep ) {
  ogg_uint32_t i;
  ogg_int16_t *TmpDataPtr = pbi->TmpDataBuffer;
  
  for ( i = 0; i < BLOCK_HEIGHT_WIDTH; i++ ){	
    /* Convert the data back to 8 bit unsigned */
    TmpDataPtr[0] = ( ChangePtr[0] + 128 );
    TmpDataPtr[1] = ( ChangePtr[1] + 128 );
    TmpDataPtr[2] = ( ChangePtr[2] + 128 );
    TmpDataPtr[3] = ( ChangePtr[3] + 128 );
    TmpDataPtr[4] = ( ChangePtr[4] + 128 );
    TmpDataPtr[5] = ( ChangePtr[5] + 128 );
    TmpDataPtr[6] = ( ChangePtr[6] + 128 );
    TmpDataPtr[7] = ( ChangePtr[7] + 128 );
    
    TmpDataPtr += BLOCK_HEIGHT_WIDTH;
    ChangePtr += BLOCK_HEIGHT_WIDTH;
  }
  
  /* Saturate the output to unsigend 8 bit values */
  SatUnsigned8( ReconPtr, pbi->TmpDataBuffer, LineStep, BLOCK_HEIGHT_WIDTH );
}

void ReconInter( PB_INSTANCE *pbi, unsigned char * ReconPtr, 
                 unsigned char * RefPtr, ogg_int16_t * ChangePtr, 
                 ogg_uint32_t LineStep ) {
  ogg_uint32_t i;
  ogg_int16_t *TmpDataPtr = pbi->TmpDataBuffer;
  
  for ( i = 0; i < BLOCK_HEIGHT_WIDTH; i++) {	
    TmpDataPtr[0] = (RefPtr[0] + ChangePtr[0]);
    TmpDataPtr[1] = (RefPtr[1] + ChangePtr[1]);
    TmpDataPtr[2] = (RefPtr[2] + ChangePtr[2]);
    TmpDataPtr[3] = (RefPtr[3] + ChangePtr[3]);
    TmpDataPtr[4] = (RefPtr[4] + ChangePtr[4]);
    TmpDataPtr[5] = (RefPtr[5] + ChangePtr[5]);
    TmpDataPtr[6] = (RefPtr[6] + ChangePtr[6]);
    TmpDataPtr[7] = (RefPtr[7] + ChangePtr[7]);
    
    ChangePtr += BLOCK_HEIGHT_WIDTH;
    TmpDataPtr += BLOCK_HEIGHT_WIDTH;
    RefPtr += LineStep; 
  }
  
  /* Saturate the output to unsigend 8 bit values */
  SatUnsigned8( ReconPtr, pbi->TmpDataBuffer, LineStep, BLOCK_HEIGHT_WIDTH );
  
}

void ReconInterHalfPixel2( PB_INSTANCE *pbi, unsigned char * ReconPtr, 
                           unsigned char * RefPtr1, unsigned char * RefPtr2, 
                           ogg_int16_t * ChangePtr, ogg_uint32_t LineStep ) {
  ogg_uint32_t  i;
  ogg_int16_t *TmpPtr = pbi->TmpDataBuffer;
  
  for ( i = 0; i < BLOCK_HEIGHT_WIDTH; i++ ){	
    TmpPtr[0] = ((((int)RefPtr1[0] + (int)RefPtr2[0]) >> 1) + ChangePtr[0] );
    TmpPtr[1] = ((((int)RefPtr1[1] + (int)RefPtr2[1]) >> 1) + ChangePtr[1] );
    TmpPtr[2] = ((((int)RefPtr1[2] + (int)RefPtr2[2]) >> 1) + ChangePtr[2] );
    TmpPtr[3] = ((((int)RefPtr1[3] + (int)RefPtr2[3]) >> 1) + ChangePtr[3] );
    TmpPtr[4] = ((((int)RefPtr1[4] + (int)RefPtr2[4]) >> 1) + ChangePtr[4] );
    TmpPtr[5] = ((((int)RefPtr1[5] + (int)RefPtr2[5]) >> 1) + ChangePtr[5] );
    TmpPtr[6] = ((((int)RefPtr1[6] + (int)RefPtr2[6]) >> 1) + ChangePtr[6] );
    TmpPtr[7] = ((((int)RefPtr1[7] + (int)RefPtr2[7]) >> 1) + ChangePtr[7] );

    ChangePtr += BLOCK_HEIGHT_WIDTH;
    TmpPtr += BLOCK_HEIGHT_WIDTH;
    RefPtr1 += LineStep; 
    RefPtr2 += LineStep; 
  }

  /* Saturate the output to unsigend 8 bit values */
  SatUnsigned8( ReconPtr, pbi->TmpDataBuffer, LineStep, BLOCK_HEIGHT_WIDTH );

}

<p><p>1.1                  theora/lib/scan.c

Index: scan.c
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: scan.c,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

#include <math.h>
#include <stdlib.h>
#include <ogg/ogg.h>
#include "encoder_internal.h"

#define MAX_SEARCH_LINE_LEN                   7

tatic ogg_uint32_t LineLengthScores[ MAX_SEARCH_LINE_LEN + 1 ] = { 
  0, 0, 0, 0, 2, 4, 12, 24 
};

tatic ogg_uint32_t BodyNeighbourScore = 8;
static double DiffDevisor = 0.0625;
#define HISTORY_BLOCK_FACTOR    2
#define MIN_STEP_THRESH 6
#define SCORE_MULT_LOW    0.5
#define SCORE_MULT_HIGH   4

#define UP      0
#define DOWN    1
#define LEFT    2
#define RIGHT   3

#define INTERNAL_BLOCK_HEIGHT   8
#define INTERNAL_BLOCK_WIDTH    8

#define BLOCK_NOT_CODED                       0
#define BLOCK_CODED_BAR                       3
#define BLOCK_CODED_SGC                       4
#define BLOCK_CODED_LOW                       4
#define BLOCK_CODED                           5

#define CANDIDATE_BLOCK_LOW                  -2
#define CANDIDATE_BLOCK                      -1

#define FIRST_ROW           0
#define NOT_EDGE_ROW        1
#define LAST_ROW            2      

#define YDIFF_CB_ROWS                   (INTERNAL_BLOCK_HEIGHT * 3)
#define CHLOCALS_CB_ROWS                (INTERNAL_BLOCK_HEIGHT * 3)
#define PMAP_CB_ROWS                    (INTERNAL_BLOCK_HEIGHT * 3)

void ConfigurePP( PP_INSTANCE *ppi, int Level ) {
  switch ( Level ){
  case 0:
    ppi->SRFGreyThresh = 1; 
    ppi->SRFColThresh = 1; 
    ppi->NoiseSupLevel = 2;
    ppi->SgcLevelThresh = 1; 
    ppi->SuvcLevelThresh = 1; 
    ppi->GrpLowSadThresh = 6;
    ppi->GrpHighSadThresh = 24;
    ppi->PrimaryBlockThreshold = 2;
    ppi->SgcThresh = 10;
    
    ppi->PAKEnabled = 0;
    break;
    
  case 1:
    ppi->SRFGreyThresh = 2; 
    ppi->SRFColThresh = 2; 
    ppi->NoiseSupLevel = 2;
    ppi->SgcLevelThresh = 2; 
    ppi->SuvcLevelThresh = 2; 
    ppi->GrpLowSadThresh = 8; 
    ppi->GrpHighSadThresh = 32;
    ppi->PrimaryBlockThreshold = 5;
    ppi->SgcThresh = 12; 
    
    ppi->PAKEnabled = 1;
    break;
    
  case 2: /* Default VP3 settings */
    ppi->SRFGreyThresh = 3; 
    ppi->SRFColThresh = 3;
    ppi->NoiseSupLevel = 2;
    ppi->SgcLevelThresh = 2;
    ppi->SuvcLevelThresh = 2;
    ppi->GrpLowSadThresh = 8;
    ppi->GrpHighSadThresh = 32;         
    ppi->PrimaryBlockThreshold = 5;
    ppi->SgcThresh = 16;
    
    ppi->PAKEnabled = 1;
    break;

  case 3:
    ppi->SRFGreyThresh = 4;
    ppi->SRFColThresh = 4;
    ppi->NoiseSupLevel = 3;
    ppi->SgcLevelThresh = 3;
    ppi->SuvcLevelThresh = 3;
    ppi->GrpLowSadThresh = 10;
    ppi->GrpHighSadThresh = 48; 
    ppi->PrimaryBlockThreshold = 5;
    ppi->SgcThresh = 18;
    
    ppi->PAKEnabled = 1;
    break;
    
  case 4:
    ppi->SRFGreyThresh = 5;
    ppi->SRFColThresh = 5;
    ppi->NoiseSupLevel = 3;
    ppi->SgcLevelThresh = 4;
    ppi->SuvcLevelThresh = 4;
    ppi->GrpLowSadThresh = 12;
    ppi->GrpHighSadThresh = 48;
    ppi->PrimaryBlockThreshold = 5;
    ppi->SgcThresh = 20;
    
    ppi->PAKEnabled = 1;
    break;

  case 5:                                                   
    ppi->SRFGreyThresh = 6;
    ppi->SRFColThresh = 6;
    ppi->NoiseSupLevel = 3;
    ppi->SgcLevelThresh = 4;
    ppi->SuvcLevelThresh = 4;
    ppi->GrpLowSadThresh = 12;
    ppi->GrpHighSadThresh = 64;
    ppi->PrimaryBlockThreshold = 10;
    ppi->SgcThresh = 24;
    
    ppi->PAKEnabled = 1;
    break;
    
  case 6:                                                   
    ppi->SRFGreyThresh = 6;
    ppi->SRFColThresh = 7;
    ppi->NoiseSupLevel = 3;
    ppi->SgcLevelThresh = 4;
    ppi->SuvcLevelThresh = 4;
    ppi->GrpLowSadThresh = 12;
    ppi->GrpHighSadThresh = 64;
    ppi->PrimaryBlockThreshold = 10;
    ppi->SgcThresh = 24;
    
    ppi->PAKEnabled = 1;
    break;

  default:
    ppi->SRFGreyThresh = 3; 
    ppi->SRFColThresh = 3;
    ppi->NoiseSupLevel = 2;
    ppi->SgcLevelThresh = 2;
    ppi->SuvcLevelThresh = 2;
    ppi->GrpLowSadThresh = 10;
    ppi->GrpHighSadThresh = 32;         
    ppi->PrimaryBlockThreshold = 5;
    ppi->SgcThresh = 16;
    ppi->PAKEnabled = 1;
    break;
  }
}

tatic void ScanCalcPixelIndexTable(PP_INSTANCE *ppi){
  ogg_uint32_t i;
  ogg_uint32_t * PixelIndexTablePtr = ppi->ScanPixelIndexTable;
    
  /* If appropriate add on extra inices for U and V planes. */
  for ( i = 0; i < (ppi->ScanYPlaneFragments); i++ ) {
    PixelIndexTablePtr[ i ] = 
      ((i / ppi->ScanHFragments) * 
       ppi->VFragPixels * ppi->ScanConfig.VideoFrameWidth);  
    PixelIndexTablePtr[ i ] += 
      ((i % ppi->ScanHFragments) * ppi->HFragPixels);
  }
  
  PixelIndexTablePtr = &ppi->ScanPixelIndexTable[ppi->ScanYPlaneFragments];
  
  for ( i = 0; i < (ppi->ScanUVPlaneFragments * 2); i++ ){
    PixelIndexTablePtr[ i ] =  
      ((i / (ppi->ScanHFragments >> 1) ) * 
       (ppi->VFragPixels * (ppi->ScanConfig.VideoFrameWidth >> 1)) );   
    PixelIndexTablePtr[ i ] += 
      ((i % (ppi->ScanHFragments >> 1) ) * 
       ppi->HFragPixels) + ppi->YFramePixels;
    }
}

tatic void InitScanMapArrays(PP_INSTANCE *ppi){
  int i;
  unsigned char StepThresh;
  
  /* Clear down the fragment level map arrays for the current frame. */
  memset( ppi->FragScores, 0, 
          ppi->ScanFrameFragments * sizeof(*ppi->FragScores) );
  memset( ppi->SameGreyDirPixels, 0, 
          ppi->ScanFrameFragments );
  memset( ppi->FragDiffPixels, 0, 
          ppi->ScanFrameFragments );
  memset( ppi->RowChangedPixels, 0, 
          3* ppi->ScanConfig.VideoFrameHeight*sizeof(*ppi->RowChangedPixels));
  
  memset( ppi->ScanDisplayFragments, BLOCK_NOT_CODED, ppi->ScanFrameFragments);

  /* Threshold used in setting up ppi->NoiseScoreBoostTable[] */
  StepThresh = (unsigned int)(ppi->SRFGreyThresh >> 1);
  if ( StepThresh < MIN_STEP_THRESH )
    StepThresh = MIN_STEP_THRESH;
  ppi->SrfThresh = (int)ppi->SRFGreyThresh;

  /* Set up various tables used to tweak pixel score values and
     scoring rules based upon absolute value of a pixel change */
  for ( i = 0; i < 256; i++ ){
    /* Score multiplier table indexed by absolute difference. */
    ppi->AbsDiff_ScoreMultiplierTable[i] = (double)i * DiffDevisor;
    if ( ppi->AbsDiff_ScoreMultiplierTable[i] < SCORE_MULT_LOW )
      ppi->AbsDiff_ScoreMultiplierTable[i] = SCORE_MULT_LOW;
    else if ( ppi->AbsDiff_ScoreMultiplierTable[i] > SCORE_MULT_HIGH)
      ppi->AbsDiff_ScoreMultiplierTable[i] = SCORE_MULT_HIGH;

    /* Table that facilitates a relaxation of the changed locals rules
       in NoiseScoreRow() for pixels that have changed by a large
       amount. */
    if ( i < (ppi->SrfThresh + StepThresh) )
      ppi->NoiseScoreBoostTable[i] = 0;
    else if ( i < (ppi->SrfThresh + (StepThresh * 4)) )
      ppi->NoiseScoreBoostTable[i] = 1;
    else if ( i < (ppi->SrfThresh + (StepThresh * 6)) )
      ppi->NoiseScoreBoostTable[i] = 2;
    else
      ppi->NoiseScoreBoostTable[i] = 3;
    
  }
  
  /* Set various other threshold parameters. */
  
  /* Set variables that control access to the line search algorithms. */
  ppi->LineSearchTripTresh = 16;
  if ( ppi->LineSearchTripTresh > ppi->PrimaryBlockThreshold )
    ppi->LineSearchTripTresh = (unsigned int)(ppi->PrimaryBlockThreshold + 1);

  /* Adjust line search length if block threshold low */
  ppi->MaxLineSearchLen = MAX_SEARCH_LINE_LEN;
  while ( (ppi->MaxLineSearchLen > 0) && 
          (LineLengthScores[ppi->MaxLineSearchLen-1] > 
           ppi->PrimaryBlockThreshold) )
    ppi->MaxLineSearchLen -= 1;

}

void ScanYUVInit( PP_INSTANCE *  ppi, SCAN_CONFIG_DATA * ScanConfigPtr){  
  int i;

  /* Set up the various imported data structure pointers. */
  ppi->ScanConfig.Yuv0ptr = ScanConfigPtr->Yuv0ptr;
  ppi->ScanConfig.Yuv1ptr = ScanConfigPtr->Yuv1ptr;
  ppi->ScanConfig.SrfWorkSpcPtr = ScanConfigPtr->SrfWorkSpcPtr;
  ppi->ScanConfig.disp_fragments = ScanConfigPtr->disp_fragments;
  
  ppi->ScanConfig.RegionIndex = ScanConfigPtr->RegionIndex;
  ppi->ScanConfig.HFragPixels = ScanConfigPtr->HFragPixels;
  ppi->ScanConfig.VFragPixels = ScanConfigPtr->VFragPixels;
  
  ppi->ScanConfig.VideoFrameWidth = ScanConfigPtr->VideoFrameWidth;
  ppi->ScanConfig.VideoFrameHeight = ScanConfigPtr->VideoFrameHeight;
  
  /* UV plane sizes. */
  ppi->VideoUVPlaneWidth = ScanConfigPtr->VideoFrameWidth / 2;
  ppi->VideoUVPlaneHeight = ScanConfigPtr->VideoFrameHeight / 2;
  
  /* Note the size of the entire frame and plaes in pixels. */
  ppi->YFramePixels = ppi->ScanConfig.VideoFrameWidth * 
    ppi->ScanConfig.VideoFrameHeight;
  ppi->UVFramePixels = ppi->VideoUVPlaneWidth * ppi->VideoUVPlaneHeight;

  /* Work out various fragment related values. */
  ppi->ScanYPlaneFragments = ppi->YFramePixels / 
    (ppi->HFragPixels * ppi->VFragPixels);
  ppi->ScanUVPlaneFragments = ppi->UVFramePixels / 
    (ppi->HFragPixels * ppi->VFragPixels);;
  ppi->ScanHFragments = ppi->ScanConfig.VideoFrameWidth / ppi->HFragPixels;
  ppi->ScanVFragments = ppi->ScanConfig.VideoFrameHeight / ppi->VFragPixels;
  ppi->ScanFrameFragments = ppi->ScanYPlaneFragments + 
    (2 * ppi->ScanUVPlaneFragments);

  PInitFrameInfo(ppi);
  
  /* Set up the scan pixel index table. */
  ScanCalcPixelIndexTable(ppi);
  
  /* Initialise the previous frame block history lists */
  for ( i = 0; i < MAX_PREV_FRAMES; i++ )
    memset( ppi->PrevFragments[i], BLOCK_NOT_CODED, ppi->ScanFrameFragments);
  
  /* YUVAnalyseFrame() is not called for the first frame in a sequence
     (a key frame obviously).  This memset insures that for the second
     frame all blocks are marked for coding in line with the behaviour
     for other key frames. */
  memset( ppi->PrevFragments[ppi->PrevFrameLimit-1], 
          BLOCK_CODED, ppi->ScanFrameFragments );

  /* Initialise scan arrays */
  InitScanMapArrays(ppi);
}

tatic void SetFromPrevious(PP_INSTANCE *ppi) { 
  unsigned int  i,j;
  
  /* We buld up the list of previously updated blocks in the zero
     index list of PrevFragments[] so we must start by reseting its
     contents */
  memset( ppi->PrevFragments[0], BLOCK_NOT_CODED, ppi->ScanFrameFragments );
  
  if ( ppi->PrevFrameLimit > 1 ){
    /* Now build up PrevFragments[0] from PrevFragments[1 to PrevFrameLimit] */
    for ( i = 0; i < ppi->ScanFrameFragments; i++ ){
      for ( j = 1; j < ppi->PrevFrameLimit; j++ ){
        if ( ppi->PrevFragments[j][i] > BLOCK_CODED_BAR ){
          ppi->PrevFragments[0][i] = BLOCK_CODED;
          break;
        }
      }
    }
  }
}

tatic void UpdatePreviousBlockLists(PP_INSTANCE *ppi) { 
  int  i;

  /* Shift previous frame block lists along. */
  for ( i = ppi->PrevFrameLimit; i > 1; i-- ){
    memcpy( ppi->PrevFragments[i], ppi->PrevFragments[i-1], 
            ppi->ScanFrameFragments );
  }

  /* Now copy in this frames block list */
  memcpy( ppi->PrevFragments[1], ppi->ScanDisplayFragments, 
          ppi->ScanFrameFragments );
}

tatic void CreateOutputDisplayMap( PP_INSTANCE *ppi,
                                    char *InternalFragmentsPtr, 
                                    char *RecentHistoryPtr,
                                    unsigned char *ExternalFragmentsPtr ) { 
  ogg_uint32_t i;
  ogg_uint32_t HistoryBlocksAdded = 0;
  ogg_uint32_t KFScore = 0;
  ogg_uint32_t YBand =  (ppi->ScanYPlaneFragments/8);   /* 1/8th of Y image. */
  
  ppi->OutputBlocksUpdated = 0;
  for ( i = 0; i < ppi->ScanFrameFragments; i++ ) {
    if ( InternalFragmentsPtr[i] > BLOCK_NOT_CODED ) {
      ppi->OutputBlocksUpdated ++;
      ExternalFragmentsPtr[i] = 1;
    }else if ( RecentHistoryPtr[i] == BLOCK_CODED ){
      HistoryBlocksAdded ++;
      ExternalFragmentsPtr[i] = 1;
    }else{
      ExternalFragmentsPtr[i] = 0;
    }
  }

  /* Add in a weighting for the history blocks that have been added */
  ppi->OutputBlocksUpdated += (HistoryBlocksAdded / HISTORY_BLOCK_FACTOR);

  /* Now calculate a key frame candidate indicator.  This is based
     upon Y data only and only ignores the top and bottom 1/8 of the
     image.  Also ignore history blocks and BAR blocks. */
  ppi->KFIndicator = 0;
  for ( i = YBand; i < (ppi->ScanYPlaneFragments - YBand); i++ )
    if ( InternalFragmentsPtr[i] > BLOCK_CODED_BAR )
      ppi->KFIndicator ++;

  /* Convert the KF score to a range 0-100 */
  ppi->KFIndicator = ((ppi->KFIndicator*100)/((ppi->ScanYPlaneFragments*3)/4));
}

tatic ogg_uint32_t ScalarRowSAD( unsigned char * Src1, 
                                  unsigned char * Src2 ){
  ogg_uint32_t SadValue;
  ogg_uint32_t SadValue1;
  
  SadValue    = abs( Src1[0] - Src2[0] ) + abs( Src1[1] - Src2[1] ) + 
    abs( Src1[2] - Src2[2] ) + abs( Src1[3] - Src2[3] );
  
  SadValue1   = abs( Src1[4] - Src2[4] ) + abs( Src1[5] - Src2[5] ) + 
    abs( Src1[6] - Src2[6] ) + abs( Src1[7] - Src2[7] );
  
  SadValue = ( SadValue > SadValue1 ) ? SadValue : SadValue1;
  
  return SadValue;
}

tatic ogg_uint32_t ScalarColSAD( PP_INSTANCE *ppi, 
                           unsigned char * Src1, 
                           unsigned char * Src2 ){
  ogg_uint32_t SadValue[8] = {0,0,0,0,0,0,0,0};
  ogg_uint32_t SadValue2[8] = {0,0,0,0,0,0,0,0};
  ogg_uint32_t MaxSad = 0;
  ogg_uint32_t i;
  
  for ( i = 0; i < 4; i++ ){
    SadValue[0] += abs(Src1[0] - Src2[0]);
    SadValue[1] += abs(Src1[1] - Src2[1]);
    SadValue[2] += abs(Src1[2] - Src2[2]);
    SadValue[3] += abs(Src1[3] - Src2[3]);
    SadValue[4] += abs(Src1[4] - Src2[4]);
    SadValue[5] += abs(Src1[5] - Src2[5]);
    SadValue[6] += abs(Src1[6] - Src2[6]);
    SadValue[7] += abs(Src1[7] - Src2[7]);
    
    Src1 += ppi->PlaneStride;
    Src2 += ppi->PlaneStride;
  }
  
  for ( i = 0; i < 4; i++ ){
    SadValue2[0] += abs(Src1[0] - Src2[0]);
    SadValue2[1] += abs(Src1[1] - Src2[1]);
    SadValue2[2] += abs(Src1[2] - Src2[2]);
    SadValue2[3] += abs(Src1[3] - Src2[3]);
    SadValue2[4] += abs(Src1[4] - Src2[4]);
    SadValue2[5] += abs(Src1[5] - Src2[5]);
    SadValue2[6] += abs(Src1[6] - Src2[6]);
    SadValue2[7] += abs(Src1[7] - Src2[7]);
    
    Src1 += ppi->PlaneStride;
    Src2 += ppi->PlaneStride;
  }
  
  for ( i = 0; i < 8; i++ ){
    if ( SadValue[i] > MaxSad )
      MaxSad = SadValue[i];
    if ( SadValue2[i] > MaxSad )
      MaxSad = SadValue2[i];
  }
  
  return MaxSad;
}

<p>static int RowSadScan( PP_INSTANCE *ppi, 
                       unsigned char * YuvPtr1, 
                       unsigned char * YuvPtr2, 
                       signed char *  DispFragPtr){
  ogg_int32_t    i, j;
  ogg_uint32_t   GrpSad;
  ogg_uint32_t   LocalGrpLowSadThresh = ppi->ModifiedGrpLowSadThresh;
  ogg_uint32_t   LocalGrpHighSadThresh = ppi->ModifiedGrpHighSadThresh;
  signed char   *LocalDispFragPtr;
  unsigned char *LocalYuvPtr1;
  unsigned char *LocalYuvPtr2;
  
  int           InterestingBlocksInRow = 0;

  /* For each row of pixels in the row of blocks */
  for ( j = 0; j < ppi->VFragPixels; j++ ){
    /* Set local block map pointer. */
    LocalDispFragPtr = DispFragPtr;
    
    /* Set the local pixel data pointers for this row.*/
    LocalYuvPtr1 = YuvPtr1;
    LocalYuvPtr2 = YuvPtr2;
    
    /* Scan along the row of pixels If the block to which a group of
       pixels belongs is already marked for update then do nothing. */
    for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
      if ( *LocalDispFragPtr <= BLOCK_NOT_CODED ){
        /* Calculate the SAD score for the block row */
        ScalarRowSAD(LocalYuvPtr1,LocalYuvPtr2);

        /* Now test the group SAD score */
        if ( GrpSad > LocalGrpLowSadThresh ){
          /* If SAD very high we must update else we have candidate block */
          if ( GrpSad > LocalGrpHighSadThresh ){
            /* Force update */
            *LocalDispFragPtr = BLOCK_CODED;
          }else{
            /* Possible Update required */
            *LocalDispFragPtr = CANDIDATE_BLOCK;
          }
          InterestingBlocksInRow = 1;
        }
      }
      LocalDispFragPtr++;
      
      LocalYuvPtr1 += 8;
      LocalYuvPtr2 += 8;
    }
    
    /* Increment the base data pointers to the start of the next line. */
    YuvPtr1 += ppi->PlaneStride;
    YuvPtr2 += ppi->PlaneStride;
  }
  
  return InterestingBlocksInRow;

}

tatic int ColSadScan( PP_INSTANCE *ppi, 
                       unsigned char * YuvPtr1, 
                       unsigned char * YuvPtr2, 
                       signed char *  DispFragPtr ){
  ogg_int32_t     i;
  ogg_uint32_t    MaxSad;
  ogg_uint32_t    LocalGrpLowSadThresh = ppi->ModifiedGrpLowSadThresh;
  ogg_uint32_t    LocalGrpHighSadThresh = ppi->ModifiedGrpHighSadThresh;
  signed char   * LocalDispFragPtr;
  
  unsigned char * LocalYuvPtr1;          
  unsigned char * LocalYuvPtr2;

  int     InterestingBlocksInRow = 0;

  /* Set the local pixel data pointers for this row. */
  LocalYuvPtr1 = YuvPtr1;
  LocalYuvPtr2 = YuvPtr2;
  
  /* Set local block map pointer. */
  LocalDispFragPtr = DispFragPtr;
  
  /* Scan along the row of blocks */
  for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
    /* Skip if block already marked to be coded. */
    if ( *LocalDispFragPtr <= BLOCK_NOT_CODED ){
      /* Calculate the SAD score for the block column */
      MaxSad = ColSAD( ppi, LocalYuvPtr1, LocalYuvPtr2 );

      /* Now test the group SAD score */
      if ( MaxSad > LocalGrpLowSadThresh ){
        /* If SAD very high we must update else we have candidate block */
        if ( MaxSad > LocalGrpHighSadThresh ){
          /* Force update */
          *LocalDispFragPtr = BLOCK_CODED;
        }else{
          /* Possible Update required */
          *LocalDispFragPtr = CANDIDATE_BLOCK;
        }
        InterestingBlocksInRow = 1;
      }
    }
    
    /* Increment the block map pointer. */
    LocalDispFragPtr++;                     
    
    /* Step data pointers on ready for next block */
    LocalYuvPtr1 += ppi->HFragPixels;
    LocalYuvPtr2 += ppi->HFragPixels;
  }

  return InterestingBlocksInRow;
}

tatic void SadPass2( PP_INSTANCE *ppi, 
                      ogg_int32_t RowNumber, 
                      signed char *  DispFragPtr ){
  ogg_int32_t  i;
  
  /* First row */
  if ( RowNumber == 0 ) {
    /* First block in row. */
    if ( DispFragPtr[0] == CANDIDATE_BLOCK ){
      if ( (DispFragPtr[1] == BLOCK_CODED) ||
           (DispFragPtr[ppi->PlaneHFragments] == BLOCK_CODED) ||
           (DispFragPtr[ppi->PlaneHFragments+1] == BLOCK_CODED) ){
        ppi->TmpCodedMap[0] =  BLOCK_CODED_LOW;
      }else{
        ppi->TmpCodedMap[0] = DispFragPtr[0];
      }
    }else{
      ppi->TmpCodedMap[0] = DispFragPtr[0];
    }
    
    /* All but first and last in row */
    for ( i = 1; (i < ppi->PlaneHFragments-1); i++ ){
      if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
        if ( (DispFragPtr[i-1] == BLOCK_CODED) || 
             (DispFragPtr[i+1] == BLOCK_CODED) ||
             (DispFragPtr[i+ppi->PlaneHFragments] == BLOCK_CODED) ||
             (DispFragPtr[i+ppi->PlaneHFragments-1] == BLOCK_CODED) ||
             (DispFragPtr[i+ppi->PlaneHFragments+1] == BLOCK_CODED) ){
          ppi->TmpCodedMap[i] =  BLOCK_CODED_LOW;
        }else{
          ppi->TmpCodedMap[i] = DispFragPtr[i];
        }
      }else{
        ppi->TmpCodedMap[i] = DispFragPtr[i];
      }
    }
    
    /* Last block in row. */
    i = ppi->PlaneHFragments-1;
    if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
      if ( (DispFragPtr[i-1] == BLOCK_CODED) || 
           (DispFragPtr[i+ppi->PlaneHFragments] == BLOCK_CODED) ||
           (DispFragPtr[i+ppi->PlaneHFragments-1] == BLOCK_CODED) ){
        ppi->TmpCodedMap[i] =  BLOCK_CODED_LOW;
      }else{
        ppi->TmpCodedMap[i] = DispFragPtr[i];
      }
    }else{
      ppi->TmpCodedMap[i] = DispFragPtr[i];
    }
  }else if ( RowNumber < (ppi->PlaneVFragments - 1) ){
    /* General case */
    /* First block in row. */
    if ( DispFragPtr[0] == CANDIDATE_BLOCK ){
      if ( (DispFragPtr[1] == BLOCK_CODED) ||
           (DispFragPtr[(-ppi->PlaneHFragments)] == BLOCK_CODED) ||
           (DispFragPtr[(-ppi->PlaneHFragments)+1] == BLOCK_CODED) ||
           (DispFragPtr[ppi->PlaneHFragments] == BLOCK_CODED) ||
           (DispFragPtr[ppi->PlaneHFragments+1] == BLOCK_CODED) ){
        ppi->TmpCodedMap[0] =  BLOCK_CODED_LOW;
      }else{
        ppi->TmpCodedMap[0] = DispFragPtr[0];
      }
    }else{
      ppi->TmpCodedMap[0] = DispFragPtr[0];
    }
    
    /* All but first and last in row */
    for ( i = 1; (i < ppi->PlaneHFragments-1); i++ ){
      if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
        if ( (DispFragPtr[i-1] == BLOCK_CODED) || 
             (DispFragPtr[i+1] == BLOCK_CODED) ||
             (DispFragPtr[i-ppi->PlaneHFragments] == BLOCK_CODED) ||
             (DispFragPtr[i-ppi->PlaneHFragments-1] == BLOCK_CODED) ||
             (DispFragPtr[i-ppi->PlaneHFragments+1] == BLOCK_CODED) ||
             (DispFragPtr[i+ppi->PlaneHFragments] == BLOCK_CODED) ||
             (DispFragPtr[i+ppi->PlaneHFragments-1] == BLOCK_CODED) ||
             (DispFragPtr[i+ppi->PlaneHFragments+1] == BLOCK_CODED) ){
          ppi->TmpCodedMap[i] =  BLOCK_CODED_LOW;
        }else{
          ppi->TmpCodedMap[i] = DispFragPtr[i];
        }
      }else{
        ppi->TmpCodedMap[i] = DispFragPtr[i];
      }
    }
    
    /* Last block in row. */
    i = ppi->PlaneHFragments-1;
    if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
      if ( (DispFragPtr[i-1] == BLOCK_CODED) || 
           (DispFragPtr[i-ppi->PlaneHFragments] == BLOCK_CODED) ||
           (DispFragPtr[i-ppi->PlaneHFragments-1] == BLOCK_CODED) ||
           (DispFragPtr[i+ppi->PlaneHFragments] == BLOCK_CODED) ||
           (DispFragPtr[i+ppi->PlaneHFragments-1] == BLOCK_CODED) ){
        ppi->TmpCodedMap[i] =  BLOCK_CODED_LOW;
      }else{
        ppi->TmpCodedMap[i] = DispFragPtr[i];
      }
    }else{
      ppi->TmpCodedMap[i] = DispFragPtr[i];
    }
  }else{
    /* Last row */
    /* First block in row. */
    if ( DispFragPtr[0] == CANDIDATE_BLOCK ){
      if ( (DispFragPtr[1] == BLOCK_CODED) ||
           (DispFragPtr[(-ppi->PlaneHFragments)] == BLOCK_CODED) ||
           (DispFragPtr[(-ppi->PlaneHFragments)+1] == BLOCK_CODED)){
        ppi->TmpCodedMap[0] =  BLOCK_CODED_LOW;
      }else{
        ppi->TmpCodedMap[0] = DispFragPtr[0];
      }
    }else{
      ppi->TmpCodedMap[0] = DispFragPtr[0];
    }
    
    /* All but first and last in row */
    for ( i = 1; (i < ppi->PlaneHFragments-1); i++ ){
      if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
        if ( (DispFragPtr[i-1] == BLOCK_CODED) || 
             (DispFragPtr[i+1] == BLOCK_CODED) ||
             (DispFragPtr[i-ppi->PlaneHFragments] == BLOCK_CODED) ||
             (DispFragPtr[i-ppi->PlaneHFragments-1] == BLOCK_CODED) ||
             (DispFragPtr[i-ppi->PlaneHFragments+1] == BLOCK_CODED) ){
          ppi->TmpCodedMap[i] =  BLOCK_CODED_LOW;
        }else{
          ppi->TmpCodedMap[i] = DispFragPtr[i];
        }
      }else{
        ppi->TmpCodedMap[i] = DispFragPtr[i];
      }
    }
    
    /* Last block in row. */
    i = ppi->PlaneHFragments-1;
    if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
      if ( (DispFragPtr[i-1] == BLOCK_CODED) || 
           (DispFragPtr[i-ppi->PlaneHFragments] == BLOCK_CODED) ||
           (DispFragPtr[i-ppi->PlaneHFragments-1] == BLOCK_CODED) ){
        ppi->TmpCodedMap[i] =  BLOCK_CODED_LOW;
      }else{
        ppi->TmpCodedMap[i] = DispFragPtr[i];
      }
    }else{
      ppi->TmpCodedMap[i] = DispFragPtr[i];
    }
  }
  
  /* Now copy back the modified Fragment data */
  memcpy( &DispFragPtr[0], &ppi->TmpCodedMap[0], (ppi->PlaneHFragments) ); 
}

tatic unsigned char ApplyPakLowPass( PP_INSTANCE *ppi, 
                                      unsigned char * SrcPtr ){
  unsigned char * SrcPtr1 = SrcPtr - 1;
  unsigned char * SrcPtr0 = SrcPtr1 - ppi->PlaneStride; /* Note the
                                                           use of
                                                           stride not
                                                           width. */
  unsigned char * SrcPtr2 = SrcPtr1 + ppi->PlaneStride;

  return  ( ( (ogg_uint32_t)SrcPtr0[0] + 
              (ogg_uint32_t)SrcPtr0[1] + 
              (ogg_uint32_t)SrcPtr0[2] +
              (ogg_uint32_t)SrcPtr1[0] + 
              (ogg_uint32_t)SrcPtr1[2] +
              (ogg_uint32_t)SrcPtr2[0] + 
              (ogg_uint32_t)SrcPtr2[1] + 
              (ogg_uint32_t)SrcPtr2[2]   ) >> 3 );
  
}

tatic void RowDiffScan( PP_INSTANCE *ppi, 
                         unsigned char * YuvPtr1, 
                         unsigned char * YuvPtr2, 
                         ogg_int16_t   * YUVDiffsPtr, 
                         unsigned char * bits_map_ptr, 
                         signed char   * SgcPtr, 
                         signed char   * DispFragPtr, 
                         unsigned char * FDiffPixels, 
                         ogg_int32_t   * RowDiffsPtr, 
                         unsigned char * ChLocalsPtr, int EdgeRow ){

  ogg_int32_t    i,j;
  ogg_int32_t    FragChangedPixels;
  
  ogg_int16_t Diff;     /* Temp local workspace. */
  
  /* Cannot use kernel if at edge or if PAK disabled */
  if ( (!ppi->PAKEnabled) || EdgeRow ){
    for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels ){
      /* Reset count of pixels changed for the current fragment. */
      FragChangedPixels = 0;
      
      /* Test for break out conditions to save time. */
      if (*DispFragPtr == CANDIDATE_BLOCK){

        /* Clear down entries in changed locals array */
        memset(ChLocalsPtr,0,8);
        
        for ( j = 0; j < ppi->HFragPixels; j++ ){
          /* Take a local copy of the measured difference. */
          Diff = (int)YuvPtr1[j] - (int)YuvPtr2[j];

          /* Store the actual difference value */
          YUVDiffsPtr[j] = Diff;

          /* Test against the Level thresholds and record the results */
          SgcPtr[0] += ppi->SgcThreshTable[Diff+255];

          /* Test against the SRF thresholds */
          bits_map_ptr[j] = ppi->SrfThreshTable[Diff+255];
          FragChangedPixels += ppi->SrfThreshTable[Diff+255];
        }
      }else{
        /* If we are breaking out here mark all pixels as changed. */
        if ( *DispFragPtr > BLOCK_NOT_CODED ){
          memset(bits_map_ptr,1,8);
          memset(ChLocalsPtr,8,8);
        }else{
          memset(ChLocalsPtr,0,8);
        }
      }

      *RowDiffsPtr += FragChangedPixels;
      *FDiffPixels += (unsigned char)FragChangedPixels;
      
      YuvPtr1 += ppi->HFragPixels;
      YuvPtr2 += ppi->HFragPixels;
      bits_map_ptr += ppi->HFragPixels;
      ChLocalsPtr += ppi->HFragPixels;
      YUVDiffsPtr += ppi->HFragPixels;
      SgcPtr ++;
      FDiffPixels ++;
      
      /* If we have a lot of changed pixels for this fragment on this
         row then the fragment is almost sure to be picked (e.g. through
         the line search) so we can mark it as selected and then ignore
         it. */
      if (FragChangedPixels >= 7){
        *DispFragPtr = BLOCK_CODED_LOW;
      }
      DispFragPtr++;    
    }
  }else{
        
    /*************************************************************/
    /* First fragment of row !! */
        
    i = 0;
    /* Reset count of pixels changed for the current fragment. */
    FragChangedPixels = 0;
    
    /* Test for break out conditions to save time. */
    if (*DispFragPtr == CANDIDATE_BLOCK){
      /* Clear down entries in changed locals array */
      memset(ChLocalsPtr,0,8);
      
      for ( j = 0; j < ppi->HFragPixels; j++ ){
        /* Take a local copy of the measured difference. */
        Diff = (int)YuvPtr1[j] - (int)YuvPtr2[j];
        
        /* Store the actual difference value */
        YUVDiffsPtr[j] = Diff;
                
        /* Test against the Level thresholds and record the results */
        SgcPtr[0] += ppi->SgcThreshTable[Diff+255];
        
        if (j>0 && ppi->SrfPakThreshTable[Diff+255] )
          Diff = (int)ApplyPakLowPass( ppi, &YuvPtr1[j] ) - 
            (int)ApplyPakLowPass( ppi, &YuvPtr2[j] );
        
        /* Test against the SRF thresholds */
        bits_map_ptr[j] = ppi->SrfThreshTable[Diff+255];
        FragChangedPixels += ppi->SrfThreshTable[Diff+255];
      }
    }else{
      /* If we are breaking out here mark all pixels as changed. */
      if ( *DispFragPtr > BLOCK_NOT_CODED ){
        memset(bits_map_ptr,1,8);
        memset(ChLocalsPtr,8,8);
      }else{
        memset(ChLocalsPtr,0,8);
      }
    }
    
    *RowDiffsPtr += FragChangedPixels;
    *FDiffPixels += (unsigned char)FragChangedPixels;
    
    YuvPtr1 += ppi->HFragPixels;
    YuvPtr2 += ppi->HFragPixels;
    bits_map_ptr += ppi->HFragPixels;
    ChLocalsPtr += ppi->HFragPixels;
    YUVDiffsPtr += ppi->HFragPixels;
    SgcPtr ++;
    FDiffPixels ++;
    
    /* If we have a lot of changed pixels for this fragment on this
       row then the fragment is almost sure to be picked
       (e.g. through the line search) so we can mark it as selected
       and then ignore it. */
    if (FragChangedPixels >= 7){
      *DispFragPtr = BLOCK_CODED_LOW;
    }
    DispFragPtr++;    
    /*************************************************************/
    /* Fragment in between!! */
    
    for ( i = ppi->HFragPixels ; i < ppi->PlaneWidth-ppi->HFragPixels; 
          i += ppi->HFragPixels ){
      /* Reset count of pixels changed for the current fragment. */
      FragChangedPixels = 0;
      
      /* Test for break out conditions to save time. */
      if (*DispFragPtr == CANDIDATE_BLOCK){
        /* Clear down entries in changed locals array */
        memset(ChLocalsPtr,0,8);
        for ( j = 0; j < ppi->HFragPixels; j++ ){
          /* Take a local copy of the measured difference. */
          Diff = (int)YuvPtr1[j] - (int)YuvPtr2[j];
          
          /* Store the actual difference value */
          YUVDiffsPtr[j] = Diff;
          
          /* Test against the Level thresholds and record the results */
          SgcPtr[0] += ppi->SgcThreshTable[Diff+255];
          
          if (ppi->SrfPakThreshTable[Diff+255] )
            Diff = (int)ApplyPakLowPass( ppi, &YuvPtr1[j] ) - 
              (int)ApplyPakLowPass( ppi, &YuvPtr2[j] );
          
          
          /* Test against the SRF thresholds */
          bits_map_ptr[j] = ppi->SrfThreshTable[Diff+255];
          FragChangedPixels += ppi->SrfThreshTable[Diff+255];
        }
      }else{
        /* If we are breaking out here mark all pixels as changed. */
        if ( *DispFragPtr > BLOCK_NOT_CODED ){
          memset(bits_map_ptr,1,8);
          memset(ChLocalsPtr,8,8);
        }else{
          memset(ChLocalsPtr,0,8);
        }
      }
      
      *RowDiffsPtr += FragChangedPixels;
      *FDiffPixels += (unsigned char)FragChangedPixels;
      
      YuvPtr1 += ppi->HFragPixels;
      YuvPtr2 += ppi->HFragPixels;
      bits_map_ptr += ppi->HFragPixels;
      ChLocalsPtr += ppi->HFragPixels;
      YUVDiffsPtr += ppi->HFragPixels;
      SgcPtr ++;
      FDiffPixels ++;
      
      /* If we have a lot of changed pixels for this fragment on this
         row then the fragment is almost sure to be picked
         (e.g. through the line search) so we can mark it as selected
         and then ignore it. */
      if (FragChangedPixels >= 7){
        *DispFragPtr = BLOCK_CODED_LOW;
      }
      DispFragPtr++;    
    }
    /*************************************************************/
    /* Last fragment of row !! */

    /* Reset count of pixels changed for the current fragment. */
    FragChangedPixels = 0;
    
    /* Test for break out conditions to save time. */
    if (*DispFragPtr == CANDIDATE_BLOCK){
      /* Clear down entries in changed locals array */
      memset(ChLocalsPtr,0,8);
      
      for ( j = 0; j < ppi->HFragPixels; j++ ){
        /* Take a local copy of the measured difference. */
        Diff = (int)YuvPtr1[j] - (int)YuvPtr2[j];
                
        /* Store the actual difference value */
        YUVDiffsPtr[j] = Diff;
                
        /* Test against the Level thresholds and record the results */
        SgcPtr[0] += ppi->SgcThreshTable[Diff+255];
        
        if (j<7 && ppi->SrfPakThreshTable[Diff+255] )
          Diff = (int)ApplyPakLowPass( ppi, &YuvPtr1[j] ) - 
            (int)ApplyPakLowPass( ppi, &YuvPtr2[j] );
        
        
        /* Test against the SRF thresholds */
        bits_map_ptr[j] = ppi->SrfThreshTable[Diff+255];
        FragChangedPixels += ppi->SrfThreshTable[Diff+255];
      }
    }else{
      /* If we are breaking out here mark all pixels as changed.*/
      if ( *DispFragPtr > BLOCK_NOT_CODED ) {
          memset(bits_map_ptr,1,8);
          memset(ChLocalsPtr,8,8);
        }else{
          memset(ChLocalsPtr,0,8);
        }
    }
    /* If we have a lot of changed pixels for this fragment on this
       row then the fragment is almost sure to be picked (e.g. through
       the line search) so we can mark it as selected and then ignore
       it. */
    *RowDiffsPtr += FragChangedPixels;
    *FDiffPixels += (unsigned char)FragChangedPixels;
    
    /* If we have a lot of changed pixels for this fragment on this
       row then the fragment is almost sure to be picked (e.g. through
       the line search) so we can mark it as selected and then ignore
       it. */
    if (FragChangedPixels >= 7){
      *DispFragPtr = BLOCK_CODED_LOW;
    }
    DispFragPtr++;    
    
  }
}

tatic void ConsolidateDiffScanResults( PP_INSTANCE *ppi, 
                                        unsigned char * FDiffPixels, 
                                        signed char * SgcScoresPtr, 
                                        signed char * DispFragPtr ){
  ogg_int32_t i;
  
  for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
    /* Consider only those blocks that were candidates in the
       difference scan. Ignore definite YES and NO cases. */
    if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
      if ( ((ogg_uint32_t)abs(SgcScoresPtr[i]) > ppi->BlockSgcThresh) ){
        /* Block marked for update due to Sgc change */
        DispFragPtr[i] = BLOCK_CODED_SGC;
      }else if ( FDiffPixels[i] == 0 ){
        /* Block is no longer a candidate for the main tests but will 
           still be considered a candidate in RowBarEnhBlockMap() */
        DispFragPtr[i] = CANDIDATE_BLOCK_LOW;
      }
    }
  }
}

tatic void RowChangedLocalsScan( PP_INSTANCE *ppi, 
                                  unsigned char * PixelMapPtr, 
                                  unsigned char * ChLocalsPtr, 
                                  signed char  * DispFragPtr, 
                                  unsigned char   RowType ){

  unsigned char changed_locals = 0; 
  unsigned char Score = 0;    
  unsigned char * PixelsChangedPtr0;
  unsigned char * PixelsChangedPtr1;
  unsigned char * PixelsChangedPtr2;
  ogg_int32_t i, j;
  ogg_int32_t LastRowIndex = ppi->PlaneWidth - 1;
  
  /* Set up the line based pointers into the bits changed map. */
  PixelsChangedPtr0 = PixelMapPtr - ppi->PlaneWidth;
  if ( PixelsChangedPtr0 < ppi->PixelChangedMap )
    PixelsChangedPtr0 += ppi->PixelMapCircularBufferSize;
  PixelsChangedPtr0 -= 1; 
  
  PixelsChangedPtr1 = PixelMapPtr - 1;
  
  PixelsChangedPtr2 = PixelMapPtr + ppi->PlaneWidth;
  if ( PixelsChangedPtr2 >= 
       (ppi->PixelChangedMap + ppi->PixelMapCircularBufferSize) )
    PixelsChangedPtr2 -= ppi->PixelMapCircularBufferSize;
  PixelsChangedPtr2 -= 1; 

  if ( RowType == NOT_EDGE_ROW ){
    /* Scan through the row of pixels and calculate changed locals. */
    for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels ){
      /* Skip a group of 8 pixels if the assosciated fragment has no
         pixels of interest. */
      if ( *DispFragPtr == CANDIDATE_BLOCK ){
        for ( j = 0; j < ppi->HFragPixels; j++ ){
          changed_locals = 0;

          /* If the pixel itself has changed */
          if ( PixelsChangedPtr1[1] ){
            if ( (i > 0) || (j > 0) ){
              changed_locals += PixelsChangedPtr0[0];
              changed_locals += PixelsChangedPtr1[0];
              changed_locals += PixelsChangedPtr2[0];
            }
            
            changed_locals += PixelsChangedPtr0[1];
            changed_locals += PixelsChangedPtr2[1];

            if ( (i + j) < LastRowIndex ){
              changed_locals += PixelsChangedPtr0[2];
              changed_locals += PixelsChangedPtr1[2];
              changed_locals += PixelsChangedPtr2[2];
            }
            
            /* Store the number of changed locals */
            *ChLocalsPtr |= changed_locals;
          }
          
          /* Increment to next pixel in the row */
          ChLocalsPtr++;
          PixelsChangedPtr0++;
          PixelsChangedPtr1++;
          PixelsChangedPtr2++;
        }
      }else{
        if ( *DispFragPtr > BLOCK_NOT_CODED )
          memset(ChLocalsPtr,0,8);
        
        /* Step pointers */
        ChLocalsPtr += ppi->HFragPixels;
        PixelsChangedPtr0 += ppi->HFragPixels;
        PixelsChangedPtr1 += ppi->HFragPixels;
        PixelsChangedPtr2 += ppi->HFragPixels;
      }
      
      /* Move on to next fragment. */
      DispFragPtr++;    
      
    }
  }else{
    /* Scan through the row of pixels and calculate changed locals. */
    for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels ){
      /* Skip a group of 8 pixels if the assosciated fragment has no
         pixels of interest */
      if ( *DispFragPtr == CANDIDATE_BLOCK ){
        for ( j = 0; j < ppi->HFragPixels; j++ ){
          changed_locals = 0;
          
          /* If the pixel itself has changed */
          if ( PixelsChangedPtr1[1] ){
            if ( RowType == FIRST_ROW ){
              if ( (i > 0) || (j > 0) ){
                changed_locals += PixelsChangedPtr1[0];
                changed_locals += PixelsChangedPtr2[0];
              }
              
              changed_locals += PixelsChangedPtr2[1];
              
              if ( (i + j) < LastRowIndex ){
                changed_locals += PixelsChangedPtr1[2];
                changed_locals += PixelsChangedPtr2[2];
              }
            }else{
              if ( (i > 0) || (j > 0 ) ){
                changed_locals += PixelsChangedPtr0[0];
                changed_locals += PixelsChangedPtr1[0];
              }
              
              changed_locals += PixelsChangedPtr0[1];
              
              if ( (i + j) < LastRowIndex ){
                changed_locals += PixelsChangedPtr0[2];
                changed_locals += PixelsChangedPtr1[2];
              }
            }
            
            /* Store the number of changed locals */
            *ChLocalsPtr |= changed_locals;
          }
          
          /* Increment to next pixel in the row */
          ChLocalsPtr++;
          PixelsChangedPtr0++;
          PixelsChangedPtr1++;
          PixelsChangedPtr2++;
        }
      }else{
        if ( *DispFragPtr > BLOCK_NOT_CODED )
          memset(ChLocalsPtr,0,8);
        
        /* Step pointers */
        ChLocalsPtr += ppi->HFragPixels;
        PixelsChangedPtr0 += ppi->HFragPixels;
        PixelsChangedPtr1 += ppi->HFragPixels;
        PixelsChangedPtr2 += ppi->HFragPixels;
      }

      /* Move on to next fragment. */
      DispFragPtr++;    
    }
  }
}

tatic void NoiseScoreRow( PP_INSTANCE *ppi, 
                           unsigned char * PixelMapPtr, 
                           unsigned char * ChLocalsPtr, 
                           ogg_int16_t   * YUVDiffsPtr, 
                           unsigned char * PixelNoiseScorePtr, 
                           ogg_uint32_t  * FragScorePtr, 
                           signed char   * DispFragPtr,
                           ogg_int32_t   * RowDiffsPtr ){ 
  ogg_int32_t i,j;
  unsigned char  changed_locals = 0; 
  ogg_int32_t  Score;
  ogg_uint32_t FragScore;
  ogg_int32_t  AbsDiff;
  
  /* For each pixel in the row */
  for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels ){
    /* Skip a group of 8 pixels if the assosciated fragment has no
       pixels of interest. */
    if ( *DispFragPtr == CANDIDATE_BLOCK ){
      /* Reset the cumulative fragment score. */
      FragScore = 0;
      
      /* Pixels grouped along the row into fragments */
      for ( j = 0; j < ppi->HFragPixels; j++ ){
        if ( PixelMapPtr[j] ){
          AbsDiff = (ogg_int32_t)( abs(YUVDiffsPtr[j]) );
          changed_locals = ChLocalsPtr[j];
          
          /* Give this pixel a score based on changed locals and level
             of its own change. */
          Score = (1 + ((ogg_int32_t)(changed_locals + 
                                      ppi->NoiseScoreBoostTable[AbsDiff]) - 
                        ppi->NoiseSupLevel));  
          
          /* For no zero scores adjust by a level based score multiplier. */
          if ( Score > 0 ){
            Score = ((double)Score * 
                     ppi->AbsDiff_ScoreMultiplierTable[AbsDiff] );
            if ( Score < 1 )
              Score = 1;
          }else{
            /* Set -ve values to 0 */
            Score = 0;
            
            /* If there are no changed locals then clear the pixel
               changed flag and decrement the pixels changed in
               fragment count to speed later stages. */
            if ( changed_locals == 0 ){
              PixelMapPtr[j] = 0; 
              *RowDiffsPtr -= 1;
            }
          }
          
          /* Update the pixel scores etc. */
          PixelNoiseScorePtr[j] = (unsigned char)Score;
          FragScore += (ogg_uint32_t)Score;
        }
      }
      
      /* Add fragment score (with plane correction factor) into main
         data structure */
      *FragScorePtr += (ogg_int32_t)(FragScore * 
                                     ppi->YUVPlaneCorrectionFactor);
      
      /* If score is greater than trip threshold then mark blcok for update. */
      if ( *FragScorePtr > ppi->BlockThreshold ){
        *DispFragPtr = BLOCK_CODED_LOW;
      }
    }
    
    /* Increment the various pointers */
    FragScorePtr++;
    DispFragPtr++;
    PixelNoiseScorePtr += ppi->HFragPixels;
    PixelMapPtr += ppi->HFragPixels;
    ChLocalsPtr += ppi->HFragPixels;
    YUVDiffsPtr += ppi->HFragPixels;
  }
}

tatic void PrimaryEdgeScoreRow( PP_INSTANCE *ppi, 
                                 unsigned char * ChangedLocalsPtr, 
                                 ogg_int16_t   * YUVDiffsPtr, 
                                 unsigned char * PixelNoiseScorePtr, 
                                 ogg_uint32_t  * FragScorePtr,
                                 signed char   * DispFragPtr,
                                 unsigned char   RowType ){ 
  ogg_uint32_t     BodyNeighbours;
  ogg_uint32_t     AbsDiff;
  unsigned char    changed_locals = 0; 
  ogg_int32_t      Score;
  ogg_uint32_t     FragScore;
  unsigned char  * CHLocalsPtr0;
  unsigned char  * CHLocalsPtr1;
  unsigned char  * CHLocalsPtr2;
  ogg_int32_t      i,j;
  ogg_int32_t      LastRowIndex = ppi->PlaneWidth - 1;

  /* Set up pointers into the current previous and next row of the
     changed locals data structure. */
  CHLocalsPtr0 = ChangedLocalsPtr - ppi->PlaneWidth;
  if ( CHLocalsPtr0 < ppi->ChLocals )
    CHLocalsPtr0 += ppi->ChLocalsCircularBufferSize;
  CHLocalsPtr0 -= 1;      
  
  CHLocalsPtr1 = ChangedLocalsPtr - 1;
  
  CHLocalsPtr2 = ChangedLocalsPtr + ppi->PlaneWidth;
  if ( CHLocalsPtr2 >= (ppi->ChLocals + ppi->ChLocalsCircularBufferSize) )
    CHLocalsPtr2 -= ppi->ChLocalsCircularBufferSize;
  CHLocalsPtr2 -= 1;      
  
  
  /* The defining rule used here is as follows. */
  /* An edge pixels has 3-5 changed locals. */
  /* And one or more of these changed locals has itself got 7-8
     changed locals. */

  if ( RowType == NOT_EDGE_ROW ){
    /* Loop for all pixels in the row. */
    for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels ){
      /* Does the fragment contain anything interesting to work with. */
      if ( *DispFragPtr == CANDIDATE_BLOCK ){
        /* Reset the cumulative fragment score. */
        FragScore = 0;
        
        /* Pixels grouped along the row into fragments */
        for ( j = 0; j < ppi->HFragPixels; j++ ){
          /* How many changed locals has the current pixel got. */
          changed_locals = ChangedLocalsPtr[j];
          
          /* Is the pixel a suitable candidate */
          if ( (changed_locals > 2) && (changed_locals < 6) ){
            /* The pixel may qualify... have a closer look.  */
            BodyNeighbours = 0;
            
            /* Count the number of "BodyNeighbours" .. Pixels that
               have 7 or more changed neighbours.  */
            if ( (i > 0) || (j > 0 ) ){
              if ( CHLocalsPtr0[0] >= 7 )
                BodyNeighbours++;
              if ( CHLocalsPtr1[0] >= 7 )
                BodyNeighbours++;
              if ( CHLocalsPtr2[0] >= 7 )
                BodyNeighbours++;
            }
            
            if ( CHLocalsPtr0[1] >= 7 )
              BodyNeighbours++;
            if ( CHLocalsPtr2[1] >= 7 )
              BodyNeighbours++;
            
            if ( (i + j) < LastRowIndex ){
              if ( CHLocalsPtr0[2] >= 7 )
                BodyNeighbours++;
              if ( CHLocalsPtr1[2] >= 7 )
                BodyNeighbours++;
              if ( CHLocalsPtr2[2] >= 7 )
                BodyNeighbours++;
            }
            
            if ( BodyNeighbours > 0 ){
              AbsDiff = abs( YUVDiffsPtr[j] );
              Score = (ogg_int32_t)
                ( (double)(BodyNeighbours * 
                           BodyNeighbourScore) * 
                  ppi->AbsDiff_ScoreMultiplierTable[AbsDiff] );
              if ( Score < 1 )
                Score = 1;
              
              /* Increment the score by a value determined by the
                 number of body neighbours. */
              PixelNoiseScorePtr[j] += (unsigned char)Score;  
              FragScore += (ogg_uint32_t)Score;
            }
          }
          
          /* Increment pointers into changed locals buffer */
          CHLocalsPtr0 ++;
          CHLocalsPtr1 ++;
          CHLocalsPtr2 ++;
        }
        
        /* Add fragment score (with plane correction factor) into main
           data structure */
        *FragScorePtr += (ogg_int32_t)(FragScore * 
                                       ppi->YUVPlaneCorrectionFactor);
        
        /* If score is greater than trip threshold then mark blcok for
           update. */
        if ( *FragScorePtr > ppi->BlockThreshold ){
          *DispFragPtr = BLOCK_CODED_LOW;
        }
        
      }else{
        /* Nothing to do for this fragment group */
        /* Advance pointers into changed locals buffer */
        CHLocalsPtr0 += ppi->HFragPixels;
        CHLocalsPtr1 += ppi->HFragPixels;
        CHLocalsPtr2 += ppi->HFragPixels;
      }
      
      /* Increment the various pointers */
      FragScorePtr++;
      DispFragPtr++;
      PixelNoiseScorePtr += ppi->HFragPixels;
      ChangedLocalsPtr += ppi->HFragPixels;
      YUVDiffsPtr += ppi->HFragPixels;
    }  
  }else{
    /* This is either the top or bottom row of pixels in a plane. */
    /* Loop for all pixels in the row. */
    for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels ){
      /* Does the fragment contain anything interesting to work with. */
      if ( *DispFragPtr == CANDIDATE_BLOCK ){
        /* Reset the cumulative fragment score. */
        FragScore = 0;
        
        /* Pixels grouped along the row into fragments */
        for ( j = 0; j < ppi->HFragPixels; j++ ){
          /* How many changed locals has the current pixel got. */
          changed_locals = ChangedLocalsPtr[j];
          
          /* Is the pixel a suitable candidate */
          if ( (changed_locals > 2) && (changed_locals < 6) ){
            /* The pixel may qualify... have a closer look. */
            BodyNeighbours = 0;
            
            /* Count the number of "BodyNeighbours" .. Pixels
               that have 7 or more changed neighbours. */
            if ( RowType == LAST_ROW ){
              /* Test for cases where it could be the first pixel on
                 the line */
              if ( (i > 0) || (j > 0) ){
                if ( CHLocalsPtr0[0] >= 7 )
                  BodyNeighbours++;
                if ( CHLocalsPtr1[0] >= 7 )
                  BodyNeighbours++;
              }
              
              if ( CHLocalsPtr0[1] >= 7 )
                BodyNeighbours++;
              
              // Test for the end of line case
              if ( (i + j) < LastRowIndex ){
                if ( CHLocalsPtr0[2] >= 7 )
                  BodyNeighbours++;
                
                if ( CHLocalsPtr1[2] >= 7 )
                  BodyNeighbours++;
              }
            }else{
              /* First Row */
              /* Test for cases where it could be the first pixel on
                 the line */
              if ( (i > 0) || (j > 0) ){
                if ( CHLocalsPtr1[0] >= 7 )
                  BodyNeighbours++;
                if ( CHLocalsPtr2[0] >= 7 )
                  BodyNeighbours++;
              }
              
              /* Test for the end of line case */
              if ( CHLocalsPtr2[1] >= 7 )
                BodyNeighbours++;
              
              if ( (i + j) < LastRowIndex ){
                if ( CHLocalsPtr1[2] >= 7 )
                  BodyNeighbours++;
                if ( CHLocalsPtr2[2] >= 7 )
                  BodyNeighbours++;
              }
            }
            
            /* Allocate a score according to the number of Body neighbours. */
            if ( BodyNeighbours > 0 ){
              AbsDiff = abs( YUVDiffsPtr[j] );
              Score = (ogg_int32_t)
                ( (double)(BodyNeighbours * BodyNeighbourScore) * 
                  ppi->AbsDiff_ScoreMultiplierTable[AbsDiff] );
              if ( Score < 1 )
                Score = 1;
              
              PixelNoiseScorePtr[j] += (unsigned char)Score;  
              FragScore += (ogg_uint32_t)Score;
            }
          }
          
          /* Increment pointers into changed locals buffer */
          CHLocalsPtr0 ++;
          CHLocalsPtr1 ++;
          CHLocalsPtr2 ++;
        }

        /* Add fragment score (with plane correction factor) into main
           data structure */
        *FragScorePtr += 
          (ogg_int32_t)(FragScore * ppi->YUVPlaneCorrectionFactor);
        
        /* If score is greater than trip threshold then mark blcok for
           update. */
        if ( *FragScorePtr > ppi->BlockThreshold ){
          *DispFragPtr = BLOCK_CODED_LOW;
        }
        
      }else{
        /* Nothing to do for this fragment group */
        /* Advance pointers into changed locals buffer */
        CHLocalsPtr0 += ppi->HFragPixels;
        CHLocalsPtr1 += ppi->HFragPixels;
        CHLocalsPtr2 += ppi->HFragPixels;
      }
      
      /* Increment the various pointers */
      FragScorePtr++;
      DispFragPtr++;
      PixelNoiseScorePtr += ppi->HFragPixels;
      ChangedLocalsPtr += ppi->HFragPixels;
      YUVDiffsPtr += ppi->HFragPixels;
    }  
  }
}

tatic void PixelLineSearch( PP_INSTANCE *ppi, 
                             unsigned char * ChangedLocalsPtr, 
                             ogg_int32_t RowNumber, 
                             ogg_int32_t ColNumber, 
                             unsigned char direction, 
                             ogg_uint32_t * line_length ){   
  /* Exit if the pixel does not qualify or we have fallen off the edge    
     of either the image plane or the row. */
  if ( ((*ChangedLocalsPtr) <= 1) ||
       ((*ChangedLocalsPtr) >= 6) ||
       (RowNumber < 0) ||
       (RowNumber >= ppi->PlaneHeight) ||
       (ColNumber < 0) ||
       (ColNumber >= ppi->PlaneWidth) ){
    /* If not then it isn't part of any line. */
    return;
  }

  if (*line_length < ppi->MaxLineSearchLen){   
    ogg_uint32_t TmpLineLength; 
    ogg_uint32_t BestLineLength;
    unsigned char * search_ptr;
    
    /* Increment the line length to include this pixel. */
    *line_length += 1;
    BestLineLength = *line_length;
    
    /* Continue search  */
    /* up */
    if ( direction == UP ){
      TmpLineLength = *line_length;
      
      search_ptr = ChangedLocalsPtr - ppi->PlaneWidth;
      if ( search_ptr < ppi->ChLocals )
        search_ptr += ppi->ChLocalsCircularBufferSize;
      
      PixelLineSearch( ppi, search_ptr, RowNumber - 1, ColNumber, 
                       direction, &TmpLineLength );    
      
      if ( TmpLineLength > BestLineLength )
        BestLineLength = TmpLineLength;
    }
    
    /* up and left */
    if ( (BestLineLength < ppi->MaxLineSearchLen) && 
         ((direction == UP) || (direction == LEFT)) ){   
      TmpLineLength = *line_length;
      
      search_ptr = ChangedLocalsPtr - ppi->PlaneWidth;
      if ( search_ptr < ppi->ChLocals )
        search_ptr += ppi->ChLocalsCircularBufferSize;
      search_ptr -= 1;
      
      PixelLineSearch( ppi, search_ptr, RowNumber - 1, ColNumber - 1, 
                       direction,  &TmpLineLength );    
      
      if ( TmpLineLength > BestLineLength )
        BestLineLength = TmpLineLength;
    } 
    
    /* up and right */
    if ( (BestLineLength < ppi->MaxLineSearchLen) && 
         ((direction == UP) || (direction == RIGHT)) ){   
      TmpLineLength = *line_length;
      
      search_ptr = ChangedLocalsPtr - ppi->PlaneWidth;
      if ( search_ptr < ppi->ChLocals )
        search_ptr += ppi->ChLocalsCircularBufferSize;
      search_ptr += 1;
      
      PixelLineSearch( ppi, search_ptr, RowNumber - 1, ColNumber + 1, 
                       direction, &TmpLineLength );   
      
      if ( TmpLineLength > BestLineLength )
        BestLineLength = TmpLineLength;
    }
    
    /* left */
    if ( (BestLineLength < ppi->MaxLineSearchLen) && ( direction == LEFT ) ){  
      TmpLineLength = *line_length;
      PixelLineSearch( ppi, ChangedLocalsPtr - 1, RowNumber, ColNumber - 1, 
                       direction, &TmpLineLength );    
      
      if ( TmpLineLength > BestLineLength )
        BestLineLength = TmpLineLength;
    }      
    
    /* right */
    if ( (BestLineLength < ppi->MaxLineSearchLen) && ( direction == RIGHT ) ){ 
      TmpLineLength = *line_length;
      PixelLineSearch( ppi, ChangedLocalsPtr + 1, RowNumber, ColNumber + 1, 
                       direction, &TmpLineLength );    
      
      if ( TmpLineLength > BestLineLength )
        BestLineLength = TmpLineLength;
    }
    
    /* Down */
    if ( BestLineLength < ppi->MaxLineSearchLen ){   
      TmpLineLength = *line_length;
      if ( direction == DOWN ){
        search_ptr = ChangedLocalsPtr + ppi->PlaneWidth;
        if ( search_ptr >= (ppi->ChLocals + ppi->ChLocalsCircularBufferSize) )
          search_ptr -= ppi->ChLocalsCircularBufferSize;
        
        PixelLineSearch( ppi, search_ptr, RowNumber + 1, ColNumber, direction,
                         &TmpLineLength );    
        
        if ( TmpLineLength > BestLineLength )
          BestLineLength = TmpLineLength;
      }
      
      
      /* down and left */
      if ( (BestLineLength < ppi->MaxLineSearchLen) && 
           ((direction == DOWN) || (direction == LEFT)) ){   
        TmpLineLength = *line_length;
        
        search_ptr = ChangedLocalsPtr + ppi->PlaneWidth;
        if ( search_ptr >= (ppi->ChLocals + ppi->ChLocalsCircularBufferSize) )
          search_ptr -= ppi->ChLocalsCircularBufferSize;
        search_ptr -= 1;
        
        PixelLineSearch( ppi, search_ptr, RowNumber + 1, ColNumber - 1, 
                         direction, &TmpLineLength );    
                
        if ( TmpLineLength > BestLineLength )
          BestLineLength = TmpLineLength;
      } 
      
      /* down and right */
      if ( (BestLineLength < ppi->MaxLineSearchLen) && 
           ((direction == DOWN) || (direction == RIGHT)) ){   
        TmpLineLength = *line_length;
        
        search_ptr = ChangedLocalsPtr + ppi->PlaneWidth;
        if ( search_ptr >= (ppi->ChLocals + ppi->ChLocalsCircularBufferSize) )
          search_ptr -= ppi->ChLocalsCircularBufferSize;
        search_ptr += 1;
        
        PixelLineSearch( ppi, search_ptr, RowNumber + 1, ColNumber + 1, 
                         direction, &TmpLineLength );   
        
        if ( TmpLineLength > BestLineLength )
          BestLineLength = TmpLineLength;
      }
    }    
    
    /* Note the search value for this pixel. */
    *line_length = BestLineLength;
  }
}

tatic unsigned char LineSearchScorePixel( PP_INSTANCE *ppi, 
                                           unsigned char * ChangedLocalsPtr, 
                                           ogg_int32_t RowNumber, 
                                           ogg_int32_t ColNumber ){
    ogg_uint32_t line_length = 0; 
    ogg_uint32_t line_length2 = 0; 
    ogg_uint32_t line_length_score = 0; 
    ogg_uint32_t tmp_line_length = 0; 
    ogg_uint32_t tmp_line_length2 = 0;  
    
    /* Look UP and Down */
    PixelLineSearch( ppi, ChangedLocalsPtr, RowNumber, 
                     ColNumber, UP, &tmp_line_length );

    if (tmp_line_length < ppi->MaxLineSearchLen) {
      /* Look DOWN */
      PixelLineSearch( ppi, ChangedLocalsPtr, RowNumber, 
                       ColNumber, DOWN, &tmp_line_length2 );
      line_length = tmp_line_length + tmp_line_length2 - 1; 
      
      if ( line_length > ppi->MaxLineSearchLen )
        line_length = ppi->MaxLineSearchLen;
    }else
      line_length = tmp_line_length; 
    
    /* If no max length line found then look left and right */
    if ( line_length < ppi->MaxLineSearchLen ){   
      tmp_line_length = 0;
      tmp_line_length2 = 0;
      
      PixelLineSearch( ppi, ChangedLocalsPtr, RowNumber, 
                       ColNumber, LEFT,  &tmp_line_length );
      if (tmp_line_length < ppi->MaxLineSearchLen){
        PixelLineSearch( ppi, ChangedLocalsPtr, RowNumber, 
                         ColNumber, RIGHT,  &tmp_line_length2 ); 
        line_length2 = tmp_line_length + tmp_line_length2 - 1; 
        
        if ( line_length2 > ppi->MaxLineSearchLen )
          line_length2 = ppi->MaxLineSearchLen;
      }else
        line_length2 = tmp_line_length; 
      
    }
    
    /* Take the largest line length */
    if ( line_length2 > line_length )
      line_length = line_length2;
    
    /* Create line length score */
    line_length_score = LineLengthScores[line_length];
    
    return (unsigned char)line_length_score;
}

tatic void LineSearchScoreRow( PP_INSTANCE *ppi, 
                                unsigned char * ChangedLocalsPtr, 
                                ogg_int16_t   * YUVDiffsPtr, 
                                unsigned char * PixelNoiseScorePtr, 
                                ogg_uint32_t  * FragScorePtr, 
                                signed char   * DispFragPtr,
                                ogg_int32_t     RowNumber ){ 
  ogg_uint32_t AbsDiff;
  unsigned char  changed_locals = 0; 
  ogg_int32_t  Score;
  ogg_uint32_t FragScore;
  ogg_int32_t  i,j;
  
  /* The defining rule used here is as follows. */
  /* An edge pixels has 2-5 changed locals. */
  /* And one or more of these changed locals has itself got 7-8
     changed locals. */
  
  /* Loop for all pixels in the row. */
  for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels ){
    /* Does the fragment contain anything interesting to work with. */
    if ( *DispFragPtr == CANDIDATE_BLOCK ){
      /* Reset the cumulative fragment score. */
      FragScore = 0;
      
      /* Pixels grouped along the row into fragments */
      for ( j = 0; j < ppi->HFragPixels; j++ ){
        /* How many changed locals has the current pixel got. */
        changed_locals = ChangedLocalsPtr[j];
        
        /* Is the pixel a suitable candidate for edge enhancement */
        if ( (changed_locals > 1) && (changed_locals < 6) &&
             (PixelNoiseScorePtr[j] < ppi->LineSearchTripTresh) ) {
          Score = (ogg_int32_t)
            LineSearchScorePixel( ppi, &ChangedLocalsPtr[j], RowNumber, i+j );
          
          if ( Score ){
            AbsDiff = abs( YUVDiffsPtr[j] );
            Score = (ogg_int32_t)
              ( (double)Score * ppi->AbsDiff_ScoreMultiplierTable[AbsDiff] );
            if ( Score < 1 )
              Score = 1;
            
            PixelNoiseScorePtr[j] += (unsigned char)Score;  
            FragScore += (ogg_uint32_t)Score;
          }
        }
      }
      
      /* Add fragment score (with plane correction factor) into main
         data structure */
      *FragScorePtr += 
        (ogg_int32_t)(FragScore * ppi->YUVPlaneCorrectionFactor);
      
      /* If score is greater than trip threshold then mark blcok for update. */
      if ( *FragScorePtr > ppi->BlockThreshold ){
        *DispFragPtr = BLOCK_CODED_LOW;
      }
    }
    
    /* Increment the various pointers */
    FragScorePtr++;
    DispFragPtr++;
    PixelNoiseScorePtr += ppi->HFragPixels;
    ChangedLocalsPtr += ppi->HFragPixels;
    YUVDiffsPtr += ppi->HFragPixels;
    
  }
}

tatic void RowCopy( PP_INSTANCE *ppi, ogg_uint32_t BlockMapIndex ){

  ogg_uint32_t   i,j;
  
  ogg_uint32_t   PixelIndex = ScanGetFragIndex(ppi, BlockMapIndex);
  signed char   * BlockMapPtr = &ppi->ScanDisplayFragments[BlockMapIndex];
  signed char   * PrevFragmentsPtr = &ppi->PrevFragments[0][BlockMapIndex];
  
  unsigned char  * SourcePtr;
  unsigned char  * DestPtr;
  
  /* Copy pixels from changed blocks back to reference frame. */
  for ( i = 0; i < (ogg_uint32_t)ppi->PlaneHFragments; i ++ ){
    /* If the fragement is marked for update or was recently marked
       for update (PrevFragmentsPtr[i]) */
    if ( (BlockMapPtr[i] > BLOCK_NOT_CODED) || 
         (PrevFragmentsPtr[i] == BLOCK_CODED) ){
      /* Set up the various pointers required. */
      SourcePtr = &ppi->ScanConfig.Yuv1ptr[PixelIndex];
      DestPtr = &ppi->ScanConfig.SrfWorkSpcPtr[PixelIndex];
      
      /* For each row of the block */
      for ( j = 0; j < ppi->ScanConfig.VFragPixels; j++ ){
        /* Copy the data unaltered from source to destination */
        memcpy(DestPtr,SourcePtr,8);

        /* Increment pointers for next line in the block */
        SourcePtr += ppi->PlaneWidth;
        DestPtr += ppi->PlaneWidth;
      }
    }
    
    /* Increment pixel index for next block. */
    PixelIndex += ppi->ScanConfig.HFragPixels;
  }
}

tatic void AnalysePlane( PP_INSTANCE *ppi, 
                          unsigned char * PlanePtr0, 
                          unsigned char * PlanePtr1, 
                          ogg_uint32_t FragArrayOffset, 
                          ogg_uint32_t PWidth, 
                          ogg_uint32_t PHeight, 
                          ogg_uint32_t PStride ) {
  unsigned char  * RawPlanePtr0;
  unsigned char  * RawPlanePtr1;
  
  ogg_int16_t  * YUVDiffsPtr;
  ogg_int16_t  * YUVDiffsPtr1;
  ogg_int16_t  * YUVDiffsPtr2;
  
  ogg_uint32_t FragIndex;
  ogg_uint32_t ScoreFragIndex1;
  ogg_uint32_t ScoreFragIndex2;
  ogg_uint32_t ScoreFragIndex3;
  ogg_uint32_t ScoreFragIndex4;
  
  int   UpdatedOrCandidateBlocks = 0;
  
  unsigned char  * ChLocalsPtr0;
  unsigned char  * ChLocalsPtr1;
  unsigned char  * ChLocalsPtr2;
  
  unsigned char  * PixelsChangedPtr0;
  unsigned char  * PixelsChangedPtr1;
  
  unsigned char  * PixelScoresPtr1;
  unsigned char  * PixelScoresPtr2;
  
  signed char   * DispFragPtr0;
  signed char   * DispFragPtr1;
  signed char   * DispFragPtr2;
  
  ogg_uint32_t * FragScoresPtr1;
  ogg_uint32_t * FragScoresPtr2;
  
  ogg_int32_t  * RowDiffsPtr;
  ogg_int32_t  * RowDiffsPtr1;
  ogg_int32_t  * RowDiffsPtr2;
  
  ogg_int32_t  i,j; 
  
  ogg_int32_t  RowNumber1;
  ogg_int32_t  RowNumber2;
  ogg_int32_t  RowNumber3;
  ogg_int32_t  RowNumber4;
  
  int   EdgeRow;
  ogg_int32_t  LineSearchRowNumber = 0;
        
  /* Variables used as temporary stores for frequently used values. */
  ogg_int32_t  Row0Mod3;
  ogg_int32_t  Row1Mod3;
  ogg_int32_t  Row2Mod3;
  ogg_int32_t  BlockRowPixels;
  
  /* Set pixel difference threshold */
  if ( FragArrayOffset == 0 ){
    /* Luminance */
    ppi->LevelThresh = (int)ppi->SgcLevelThresh;
    ppi->NegLevelThresh = -ppi->LevelThresh;
    
    ppi->SrfThresh = (int)ppi->SRFGreyThresh;
    ppi->NegSrfThresh = -ppi->SrfThresh;
    
    /* Scores correction for Y pixels. */
    ppi->YUVPlaneCorrectionFactor = 1.0;
    
    ppi->BlockThreshold = ppi->PrimaryBlockThreshold;
    ppi->BlockSgcThresh = ppi->SgcThresh;
  }else{
    /* Chrominance */
    ppi->LevelThresh = (int)ppi->SuvcLevelThresh;
    ppi->NegLevelThresh = -ppi->LevelThresh;
    
    ppi->SrfThresh = (int)ppi->SRFColThresh;
    ppi->NegSrfThresh = -ppi->SrfThresh;
    
    /* Scores correction for UV pixels. */
    ppi->YUVPlaneCorrectionFactor = 1.5;
    
    /* Block threholds different for subsampled U and V blocks */
    ppi->BlockThreshold = 
      (ppi->PrimaryBlockThreshold / ppi->UVBlockThreshCorrection);
    ppi->BlockSgcThresh = 
      (ppi->SgcThresh / ppi->UVSgcCorrection);
  }
  
  /* Initialise the SRF thresh table and pointer. */
  memset( ppi->SrfThreshTable, 1, 512 );
  for ( i = ppi->NegSrfThresh; i <= ppi->SrfThresh; i++ )
    ppi->SrfThreshTable[i+255] = 0;
  
  /* Initialise the PAK thresh table. */
  for ( i = -255; i <= 255; i++ )
    if ( ppi->SrfThreshTable[i+255] && 
         (i <= ppi->HighChange) && 
         (i >= ppi->NegHighChange) )
      ppi->SrfPakThreshTable[i+255] = 1;
    else
      ppi->SrfPakThreshTable[i+255] = 0;

  /* Initialise the SGc lookup table */
  for ( i = -255; i <= 255; i++ ){
    if ( i <= ppi->NegLevelThresh )
      ppi->SgcThreshTable[i+255] = -1;
    else if ( i >= ppi->LevelThresh )
      ppi->SgcThreshTable[i+255] = 1;
    else
      ppi->SgcThreshTable[i+255] = 0;
  }
  
  /* Set up plane dimension variables */
  ppi->PlaneHFragments = PWidth / ppi->HFragPixels;
  ppi->PlaneVFragments = PHeight / ppi->VFragPixels;
  ppi->PlaneWidth = PWidth;
  ppi->PlaneHeight = PHeight;
  ppi->PlaneStride = PStride;
  
  /* Set up local pointers into the raw image data. */
  RawPlanePtr0 = PlanePtr0;
  RawPlanePtr1 = PlanePtr1;
  
  /* Note size and endo points for circular buffers. */
  ppi->YuvDiffsCircularBufferSize = YDIFF_CB_ROWS * ppi->PlaneWidth;
  ppi->ChLocalsCircularBufferSize = CHLOCALS_CB_ROWS * ppi->PlaneWidth;
  ppi->PixelMapCircularBufferSize = PMAP_CB_ROWS * ppi->PlaneWidth;
  
  /* Set high change thresh where PAK not needed */
  ppi->HighChange = ppi->SrfThresh * 4;
  ppi->NegHighChange = -ppi->HighChange;
  
  /* Set up row difference pointers. */
  RowDiffsPtr = ppi->RowChangedPixels;
  RowDiffsPtr1 = ppi->RowChangedPixels;
  RowDiffsPtr2 = ppi->RowChangedPixels;
  
  BlockRowPixels = ppi->PlaneWidth * ppi->VFragPixels;
  
  for ( i = 0; i < (ppi->PlaneVFragments + 4); i++ ){
    RowNumber1 = (i - 1);
    RowNumber2 = (i - 2);
    RowNumber3 = (i - 3);
    RowNumber4 = (i - 4);
    
    /* Pre calculate some frequently used values */
    Row0Mod3 = i % 3;
    Row1Mod3 = RowNumber1 % 3;
    Row2Mod3 = RowNumber2 % 3;
    
    /*  For row diff scan last two iterations are invalid */
    if ( i < ppi->PlaneVFragments ){
      FragIndex = (i * ppi->PlaneHFragments) + FragArrayOffset;
      YUVDiffsPtr = &ppi->yuv_differences[Row0Mod3 * BlockRowPixels];
      
      PixelsChangedPtr0 = (&ppi->PixelChangedMap[Row0Mod3 * BlockRowPixels]);
      DispFragPtr0 =  &ppi->ScanDisplayFragments[FragIndex];
      
      ChLocalsPtr0 = (&ppi->ChLocals[Row0Mod3 * BlockRowPixels]);
      
    }
    
    /* Set up the changed locals pointer to trail behind by one row of
       fragments. */
    if ( i > 0 ){
      /* For last iteration the ch locals and noise scans are invalid */
      if ( RowNumber1 < ppi->PlaneVFragments ){
        ScoreFragIndex1 = (RowNumber1 * ppi->PlaneHFragments) + 
          FragArrayOffset;
        
        ChLocalsPtr1 = &ppi->ChLocals[Row1Mod3 * BlockRowPixels];
        PixelsChangedPtr1 = 
          &ppi->PixelChangedMap[(Row1Mod3) * BlockRowPixels];
      
        PixelScoresPtr1 = &ppi->PixelScores[(RowNumber1 % 4) * BlockRowPixels];
        
        YUVDiffsPtr1 = &ppi->yuv_differences[Row1Mod3 * BlockRowPixels];
        FragScoresPtr1 = &ppi->FragScores[ScoreFragIndex1];
        DispFragPtr1 = &ppi->ScanDisplayFragments[ScoreFragIndex1];
        
      }
      
      if ( RowNumber2 >= 0 ){
        ScoreFragIndex2 = (RowNumber2 * ppi->PlaneHFragments) +
          FragArrayOffset;
        ChLocalsPtr2 = (&ppi->ChLocals[Row2Mod3 * BlockRowPixels]);
        YUVDiffsPtr2 = &ppi->yuv_differences[Row2Mod3 * BlockRowPixels];
        
        PixelScoresPtr2 = &ppi->PixelScores[(RowNumber2 % 4) * BlockRowPixels];
        
        FragScoresPtr2 =  &ppi->FragScores[ScoreFragIndex2];
        DispFragPtr2 = &ppi->ScanDisplayFragments[ScoreFragIndex2];
      }else{
        ChLocalsPtr2 = NULL;
      }
    }else{
      ChLocalsPtr1 = NULL;
      ChLocalsPtr2 = NULL;
    }
    
    /* Fast break out test for obvious yes and no cases in this row of
       blocks */
    if ( i < ppi->PlaneVFragments ){
      UpdatedOrCandidateBlocks = 
        RowSadScan( ppi, RawPlanePtr0, RawPlanePtr1, DispFragPtr0 );
      if( ColSadScan( ppi, RawPlanePtr0, RawPlanePtr1, DispFragPtr0 ) )
        UpdatedOrCandidateBlocks = 1;
    }else{
      /* Make sure we still call other functions if RowSadScan() disabled */
      UpdatedOrCandidateBlocks = 1;
    }
    
    /* Consolidation and fast break ot tests at Row 1 level */
    if ( (i > 0) && (RowNumber1 < ppi->PlaneVFragments) ){
      /* Mark as coded any candidate block that lies adjacent to a
         coded block. */
      SadPass2( ppi, RowNumber1, DispFragPtr1 );
      
      /* Check results of diff scan in last set of blocks. */
      /* Eliminate NO cases and add in +SGC cases */
      ConsolidateDiffScanResults( ppi, &ppi->FragDiffPixels[ScoreFragIndex1], 
                                  &ppi->SameGreyDirPixels[ScoreFragIndex1], 
                                  DispFragPtr1 
                                  );
    }
    
    for ( j = 0; j < ppi->VFragPixels; j++ ){
      /* Last two iterations do not apply */
      if ( i < ppi->PlaneVFragments ){
        /* Is the current fragment at an edge. */
        EdgeRow = ( ( (i == 0) && (j == 0) ) ||
                    ( (i == (ppi->PlaneVFragments - 1)) && 
                      (j == (ppi->VFragPixels - 1)) ) );
        
        /* Clear the arrays that will be used for the changed pixels maps */
        memset( PixelsChangedPtr0, 0, ppi->PlaneWidth );
        
        /* Difference scan and map each row */
        if ( UpdatedOrCandidateBlocks ){
          /* Scan the row for interesting differences */
          /* Also clear the array that will be used for changed locals map */
          RowDiffScan( ppi, RawPlanePtr0, RawPlanePtr1, 
                       YUVDiffsPtr, PixelsChangedPtr0, 
                       &ppi->SameGreyDirPixels[FragIndex], 
                       DispFragPtr0, &ppi->FragDiffPixels[FragIndex], 
                       RowDiffsPtr, ChLocalsPtr0, EdgeRow);
        }else{
          /* Clear the array that will be used for changed locals map */
          memset( ChLocalsPtr0, 0, ppi->PlaneWidth );
        }
        
        /* The actual image plane pointers must be incremented by
           stride as this may be different (more) than the plane
           width. Our own internal buffers use ppi->PlaneWidth. */
        RawPlanePtr0 += ppi->PlaneStride;
        RawPlanePtr1 += ppi->PlaneStride;
        PixelsChangedPtr0 += ppi->PlaneWidth;
        ChLocalsPtr0 += ppi->PlaneWidth;
        YUVDiffsPtr += ppi->PlaneWidth;
        RowDiffsPtr++;
      }
      
      /* Run behind calculating the changed locals data and noise scores. */
      if ( ChLocalsPtr1 != NULL ){
        /* Last few iterations do not apply */
        if ( RowNumber1 < ppi->PlaneVFragments ){
          /* Blank the next row in the pixel scores data structure. */
          memset( PixelScoresPtr1, 0, ppi->PlaneWidth );
          
          /* Don't bother doing anything if there are no changed
             pixels in this row */
          if ( *RowDiffsPtr1 ){
            /* Last valid row is a special case */
            if ( i < ppi->PlaneVFragments )
              RowChangedLocalsScan( ppi, PixelsChangedPtr1, ChLocalsPtr1, 
                                    DispFragPtr1, 
                                    ( (((i-1)==0) && (j==0)) ? 
                                      FIRST_ROW : NOT_EDGE_ROW) );
            else    
              RowChangedLocalsScan( ppi, PixelsChangedPtr1, ChLocalsPtr1, 
                                    DispFragPtr1, 
                                    ((j==(ppi->VFragPixels-1)) ? 
                                     LAST_ROW : NOT_EDGE_ROW) );

            NoiseScoreRow( ppi, PixelsChangedPtr1, ChLocalsPtr1, YUVDiffsPtr1,
                           PixelScoresPtr1, FragScoresPtr1, DispFragPtr1, 
                           RowDiffsPtr1 );
          }
          
          ChLocalsPtr1 += ppi->PlaneWidth;
          PixelsChangedPtr1 += ppi->PlaneWidth;
          YUVDiffsPtr1 += ppi->PlaneWidth;
          PixelScoresPtr1 += ppi->PlaneWidth;
          RowDiffsPtr1 ++;
        }
        
        /* Run edge enhancement algorithms */
        if ( RowNumber2 < ppi->PlaneVFragments ){
          if ( ChLocalsPtr2 != NULL ){
            /* Don't bother doing anything if there are no changed
               pixels in this row */
            if ( *RowDiffsPtr2 ){
              if ( RowNumber1 < ppi->PlaneVFragments ){
                PrimaryEdgeScoreRow( ppi, ChLocalsPtr2, YUVDiffsPtr2,
                                     PixelScoresPtr2, FragScoresPtr2, 
                                     DispFragPtr2,
                                     ( (((i-2)==0) && (j==0)) ? 
                                       FIRST_ROW : NOT_EDGE_ROW)  );
              }else{
                /* Edge enhancement */
                PrimaryEdgeScoreRow( ppi, ChLocalsPtr2, YUVDiffsPtr2,
                                     PixelScoresPtr2, FragScoresPtr2, 
                                     DispFragPtr2,
                                     ((j==(ppi->VFragPixels-1)) ? 
                                      LAST_ROW : NOT_EDGE_ROW) );
              }
              
              /* Recursive line search */
              LineSearchScoreRow( ppi, ChLocalsPtr2, YUVDiffsPtr2,
                                  PixelScoresPtr2, FragScoresPtr2, 
                                  DispFragPtr2,
                                  LineSearchRowNumber );
            }
            
            ChLocalsPtr2 += ppi->PlaneWidth;
            YUVDiffsPtr2 += ppi->PlaneWidth;
            PixelScoresPtr2 += ppi->PlaneWidth;
            LineSearchRowNumber += 1;
            RowDiffsPtr2 ++;
          }
        }
      }
    }
    
    /* BAR algorithm */
    if ( (RowNumber3 >= 0) && (RowNumber3 < ppi->PlaneVFragments) ){
      ScoreFragIndex3 = (RowNumber3 * ppi->PlaneHFragments) + FragArrayOffset;
      RowBarEnhBlockMap(ppi,  &ppi->FragScores[ScoreFragIndex3], 
                        &ppi->SameGreyDirPixels[ScoreFragIndex3],
                        &ppi->ScanDisplayFragments[ScoreFragIndex3],
                        &ppi->BarBlockMap[(RowNumber3 % 3) * 
                                         ppi->PlaneHFragments],
                        RowNumber3 );
    }
    
    /* BAR copy back and "ppi->SRF filtering" or "pixel copy back" */
    if ( (RowNumber4 >= 0) && (RowNumber4 < ppi->PlaneVFragments) ){
      /* BAR copy back stage must lag by one more row to avoid BAR blocks
         being used in BAR descisions. */
      ScoreFragIndex4 = (RowNumber4 * ppi->PlaneHFragments) + FragArrayOffset;
      
      BarCopyBack(ppi, &ppi->ScanDisplayFragments[ScoreFragIndex4],
                  &ppi->BarBlockMap[(RowNumber4 % 3) * ppi->PlaneHFragments]);
      
      /* Copy over the data from any blocks marked for update into the
         output buffer. */
      RowCopy(ppi, ScoreFragIndex4);
    }
  }
}

ogg_uint32_t YUVAnalyseFrame( PP_INSTANCE *ppi, ogg_uint32_t * KFIndicator ){
  ogg_uint32_t UpdatedYBlocks = 0;
  ogg_uint32_t UpdatedUVBlocks = 0;
  
  /* Initialise the map arrays. */
  InitScanMapArrays(ppi);
  
  /* If the motion level in the previous frame was high then adjust
     the high and low SAD thresholds to speed things up. */
  ppi->ModifiedGrpLowSadThresh = ppi->GrpLowSadThresh;
  ppi->ModifiedGrpHighSadThresh = ppi->GrpHighSadThresh;
  
  
  /* Set up the internal plane height and width variables. */
  ppi->VideoYPlaneWidth = ppi->ScanConfig.VideoFrameWidth;
  ppi->VideoYPlaneHeight = ppi->ScanConfig.VideoFrameHeight;
  ppi->VideoUVPlaneWidth = ppi->ScanConfig.VideoFrameWidth / 2;
  ppi->VideoUVPlaneHeight = ppi->ScanConfig.VideoFrameHeight / 2;
  
  /* To start with the strides will be set from the widths */
  ppi->VideoYPlaneStride = ppi->VideoYPlaneWidth;
  ppi->VideoUPlaneStride = ppi->VideoUVPlaneWidth;
  ppi->VideoVPlaneStride = ppi->VideoUVPlaneWidth;
  
  /* Set up the plane pointers */
  ppi->YPlanePtr0 = ppi->ScanConfig.Yuv0ptr;
  ppi->YPlanePtr1 = ppi->ScanConfig.Yuv1ptr;
  ppi->UPlanePtr0 = (ppi->ScanConfig.Yuv0ptr + ppi->YFramePixels);
  ppi->UPlanePtr1 = (ppi->ScanConfig.Yuv1ptr + ppi->YFramePixels);
  ppi->VPlanePtr0 = (ppi->ScanConfig.Yuv0ptr + ppi->YFramePixels + 
                     ppi->UVFramePixels);
  ppi->VPlanePtr1 = (ppi->ScanConfig.Yuv1ptr + ppi->YFramePixels + 
                     ppi->UVFramePixels);
  
  /* Check previous frame lists and if necessary mark extra blocks for
     update. */
  SetFromPrevious(ppi);
  
  /* Ananlyse the U and V palnes. */
  AnalysePlane( ppi, ppi->UPlanePtr0, ppi->UPlanePtr1, 
                ppi->ScanYPlaneFragments, ppi->VideoUVPlaneWidth, 
                ppi->VideoUVPlaneHeight, ppi->VideoUPlaneStride );
  AnalysePlane( ppi, ppi->VPlanePtr0, ppi->VPlanePtr1, 
                (ppi->ScanYPlaneFragments + ppi->ScanUVPlaneFragments), 
                ppi->VideoUVPlaneWidth, ppi->VideoUVPlaneHeight, 
                ppi->VideoVPlaneStride );

  /* Now analyse the Y plane. */
  AnalysePlane( ppi, ppi->YPlanePtr0, ppi->YPlanePtr1, 0, 
                ppi->VideoYPlaneWidth, ppi->VideoYPlaneHeight,
                ppi->VideoYPlaneStride );

  /* Update the list of previous frame block updates. */
  UpdatePreviousBlockLists(ppi);
    
  /* Create an output block map for the calling process. */
  CreateOutputDisplayMap( ppi, ppi->ScanDisplayFragments, 
                          ppi->PrevFragments[0],
                          ppi->ScanConfig.disp_fragments );
  
  /* Set the candidate key frame indicator (0-100) */
  *KFIndicator = ppi->KFIndicator;
  
  /* Return the normalised block count (this is actually a motion
     level weighting not a true block count). */
  return ppi->OutputBlocksUpdated;
}

<p><p><p>1.1                  theora/lib/toplevel_lookup.h

Index: toplevel_lookup.h
===================================================================
/********************************************************************
 *                                                                  *
 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
 *                                                                  *
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
 * by the Xiph.Org Foundation http://www.xiph.org/                  *
 *                                                                  *
 ********************************************************************

  function: 
  last mod: $Id: toplevel_lookup.h,v 1.1 2002/09/20 09:30:32 xiphmont Exp $

 ********************************************************************/

ogg_uint32_t PriorKeyFrameWeight[KEY_FRAME_CONTEXT] = { 1,2,3,4,5 };

/* Data structures controlling addition of residue blocks */
ogg_uint32_t ResidueErrorThresh[Q_TABLE_SIZE] =  {    
  750, 700, 650, 600, 590, 580, 570, 560, 
  550, 540, 530, 520, 510, 500, 490, 480,  
  470, 460, 450, 440, 430, 420, 410, 400, 
  390, 380, 370, 360, 350, 340, 330, 320, 
  310, 300, 290, 280, 270, 260, 250, 245, 
  240, 235, 230, 225, 220, 215, 210, 205, 
  200, 195, 190, 185, 180, 175, 170, 165,
  160, 155, 150, 145, 140, 135, 130, 130 };
ogg_uint32_t ResidueBlockFactor[Q_TABLE_SIZE] =  {    
  3,   3,   3,   3,   3,   3,   3,   3,
  3,   3,   3,   3,   3,   3,   3,   3,
  3,   3,   3,   3,   3,   3,   3,   3,
  3,   3,   3,   3,   3,   3,   3,   3,
  2,   2,   2,   2,   2,   2,   2,   2,
  2,   2,   2,   2,   2,   2,   2,   2,
  2,   2,   2,   2,   2,   2,   2,   2,
  2,   2,   2,   2,   2,   2,   2,   2 };

<p><p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list