about summary refs log tree commit diff
path: root/converter/ppm/ppmtompeg/subsample.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/ppm/ppmtompeg/subsample.c')
-rw-r--r--converter/ppm/ppmtompeg/subsample.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/converter/ppm/ppmtompeg/subsample.c b/converter/ppm/ppmtompeg/subsample.c
new file mode 100644
index 00000000..5ec71814
--- /dev/null
+++ b/converter/ppm/ppmtompeg/subsample.c
@@ -0,0 +1,280 @@
+/*===========================================================================*
+ * subsample.c                                   *
+ *                                       *
+ *  Procedures concerned with subsampling                    *
+ *                                       *
+ * EXPORTED PROCEDURES:                              *
+ *  LumMotionErrorA                              *
+ *  LumMotionErrorB                              *
+ *  LumMotionErrorC                              *
+ *  LumMotionErrorD                              *
+ *                                       *
+ *===========================================================================*/
+
+/*
+ * Copyright (c) 1995 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+/*==============*
+ * HEADER FILES *
+ *==============*/
+
+#include "pm_c_util.h"
+#include "all.h"
+#include "mtypes.h"
+#include "frames.h"
+#include "bitio.h"
+#include "prototypes.h"
+
+
+
+static void
+computePrevFyFx(MpegFrame * const prevFrame,
+                int         const by,
+                int         const bx,
+                vector      const m,
+                uint8 ***   const prevP,
+                int *       const fyP,
+                int *       const fxP) {
+
+    boolean const xHalf = (ABS(m.x) % 2 == 1);
+    boolean const yHalf = (ABS(m.y) % 2 == 1);
+
+    MotionToFrameCoord(by, bx, m.y/2, m.x/2, fyP, fxP);
+
+    if (xHalf) {
+        if (m.x < 0)
+            --*fxP;
+
+        if (yHalf) {
+            if (m.y < 0)
+                --*fyP;
+        
+            *prevP = prevFrame->halfBoth;
+        } else
+            *prevP = prevFrame->halfX;
+    } else if (yHalf) {
+        if (m.y < 0)
+            --*fyP;
+        
+        *prevP = prevFrame->halfY;
+    } else
+        *prevP = prevFrame->ref_y;
+}
+
+
+
+static int32
+evenColDiff(const uint8 * const macross,
+            const int32 * const currentRow) {
+
+    return 0
+        + ABS(macross[ 0] - currentRow[ 0])
+        + ABS(macross[ 2] - currentRow[ 2])
+        + ABS(macross[ 4] - currentRow[ 4])
+        + ABS(macross[ 6] - currentRow[ 6])
+        + ABS(macross[ 8] - currentRow[ 8])
+        + ABS(macross[10] - currentRow[10])
+        + ABS(macross[12] - currentRow[12])
+        + ABS(macross[14] - currentRow[14]);
+}
+
+
+
+static int32
+oddColDiff(const uint8 * const macross,
+           const int32 * const currentRow) {
+
+    return 0
+        + ABS(macross[ 1] - currentRow[ 1])
+        + ABS(macross[ 3] - currentRow[ 3])
+        + ABS(macross[ 5] - currentRow[ 5])
+        + ABS(macross[ 7] - currentRow[ 7])
+        + ABS(macross[ 9] - currentRow[ 9])
+        + ABS(macross[11] - currentRow[11])
+        + ABS(macross[13] - currentRow[13])
+        + ABS(macross[15] - currentRow[15]);
+}
+
+
+
+/*===========================================================================*
+ *
+ * LumMotionErrorA
+ *
+ *  compute the motion error for the A subsampling pattern
+ *
+ * RETURNS: the error, or some number greater if it is worse
+ *
+ * SIDE EFFECTS:    none
+ *
+ *===========================================================================*/
+int32
+LumMotionErrorA(const LumBlock * const currentBlockP,
+                MpegFrame *      const prevFrame,
+                int              const by,
+                int              const bx,
+                vector           const m,
+                int32            const bestSoFar) {
+
+    int32 diff; /* max value of diff is 255*256 = 65280 */
+    uint8 ** prev;
+    int fy, fx;
+    unsigned int rowNumber;
+
+    computePrevFyFx(prevFrame, by, bx, m, &prev, &fy, &fx);
+
+    diff = 0;  /* initial value */
+
+    for (rowNumber = 0; rowNumber < 16; rowNumber +=2) {
+        uint8 *       const macross    = &(prev[fy + rowNumber][fx]);
+        const int32 * const currentRow = currentBlockP->l[rowNumber];
+
+        diff += evenColDiff(macross, currentRow);
+
+        if (diff > bestSoFar)
+            return diff;
+    }
+    return diff;
+}
+
+
+
+/*===========================================================================*
+ *
+ * LumMotionErrorB
+ *
+ *  compute the motion error for the B subsampling pattern
+ *
+ * RETURNS: the error, or some number greater if it is worse
+ *
+ * SIDE EFFECTS:    none
+ *
+ *===========================================================================*/
+int32
+LumMotionErrorB(const LumBlock * const currentBlockP,
+                MpegFrame *      const prevFrame,
+                int              const by,
+                int              const bx,
+                vector           const m,
+                int32            const bestSoFar) {
+
+    int32 diff;  /* max value of diff is 255*256 = 65280 */
+    uint8 **prev;
+    int fy, fx;
+    unsigned int rowNumber;
+
+    computePrevFyFx(prevFrame, by, bx, m, &prev, &fy, &fx);
+
+    diff = 0;  /* initial value */
+    
+    for (rowNumber = 0; rowNumber < 16; rowNumber +=2) {
+        uint8 *       const macross    = &(prev[fy + rowNumber][fx]);
+        const int32 * const currentRow = currentBlockP->l[rowNumber];
+
+        diff += oddColDiff(macross, currentRow);
+
+        if (diff > bestSoFar)
+            return diff;
+    }
+    return diff;
+}
+
+
+/*===========================================================================*
+ *
+ * LumMotionErrorC
+ *
+ *  compute the motion error for the C subsampling pattern
+ *
+ * RETURNS: the error, or some number greater if it is worse
+ *
+ * SIDE EFFECTS:    none
+ *
+ *===========================================================================*/
+int32
+LumMotionErrorC(const LumBlock * const currentBlockP,
+                MpegFrame *      const prevFrame,
+                int              const by,
+                int              const bx,
+                vector           const m,
+                int32            const bestSoFar) {
+
+    int32 diff;        /* max value of diff is 255*256 = 65280 */
+    uint8 **prev;
+    int fy, fx;
+    unsigned int rowNumber;
+
+    computePrevFyFx(prevFrame, by, bx, m, &prev, &fy, &fx);
+
+    diff = 0;  /* initial value */
+    
+    for (rowNumber = 1; rowNumber < 16; rowNumber +=2) {
+        uint8 *       const macross    = &(prev[fy + rowNumber][fx]);
+        const int32 * const currentRow = currentBlockP->l[rowNumber];
+
+        diff += evenColDiff(macross, currentRow);
+
+        if (diff > bestSoFar)
+            return diff;
+    }
+    return diff;
+}
+
+
+/*===========================================================================*
+ *
+ * LumMotionErrorD
+ *
+ *  compute the motion error for the D subsampling pattern
+ *
+ * RETURNS: the error, or some number greater if it is worse
+ *
+ * SIDE EFFECTS:    none
+ *
+ *===========================================================================*/
+int32
+LumMotionErrorD(const LumBlock * const currentBlockP,
+                MpegFrame *      const prevFrame,
+                int              const by,
+                int              const bx,
+                vector           const m,
+                int32            const bestSoFar) {
+
+    int32 diff;     /* max value of diff is 255*256 = 65280 */
+    uint8 ** prev;
+    int fy, fx;
+    unsigned int rowNumber;
+
+    computePrevFyFx(prevFrame, by, bx, m, &prev, &fy, &fx);
+
+    diff = 0;  /* initial value */
+
+    for (rowNumber = 1; rowNumber < 16; rowNumber +=2) {
+        uint8 *       const macross    = &(prev[fy + rowNumber][fx]);
+        const int32 * const currentRow = currentBlockP->l[rowNumber];
+
+        diff += oddColDiff(macross, currentRow);
+
+        if (diff > bestSoFar)
+            return diff;
+    }
+    return diff;
+}