diff options
Diffstat (limited to 'converter/ppm/ppmtompeg/subsample.c')
-rw-r--r-- | converter/ppm/ppmtompeg/subsample.c | 280 |
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; +} |