/* * predictor.c -- * * Code for predictor calculation. Its macro version, predictor.h, * is used in non-debugging compilation. * * Copyright (c) 1994 Kongji Huang and Brian C. Smith. * Cornell University * 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 CORNELL UNIVERSITY 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 CORNELL * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * CORNELL UNIVERSITY 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 CORNELL UNIVERSITY HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ #include #include "mcu.h" #ifdef DEBUG /* *-------------------------------------------------------------- * * Predict -- * * Calculate the predictor for pixel[row][col][curComp], * i.e. curRowBuf[col][curComp]. It handles the all special * cases at image edges, such as first row and first column * of a scan. * * Results: * predictor is passed out. * * Side effects: * None. * *-------------------------------------------------------------- */ void Predict(row,col,curComp,curRowBuf,prevRowBuf,Pr,Pt,psv,predictor) int row,col; /* position of the pixel to be predicted */ int curComp; /* the pixel's component that is predicting */ MCU *curRowBuf,*prevRowBuf; /* current and previous row of image */ int Pr; /* data precision */ int Pt; /* point transformation */ int psv; /* predictor selection value */ int *predictor; /* preditor value (output) */ { register int left,upper,diag,leftcol; leftcol=col-1; if (row==0) { /* * The predictor of first pixel is (1<<(Pr-Pt-1), and the * predictors for rest of first row are left neighbors. */ if (col==0) { *predictor = (1<<(Pr-Pt-1)); } else { *predictor = curRowBuf[leftcol][curComp]; } } else { /* * The predictors of first column are upper neighbors. * All other preditors are calculated according to psv. */ upper=prevRowBuf[col][curComp]; if (col==0) *predictor = upper; else { left=curRowBuf[leftcol][curComp]; diag=prevRowBuf[leftcol][curComp]; switch (psv) { case 0: *predictor = 0; break; case 1: *predictor = left; break; case 2: *predictor = upper; break; case 3: *predictor = diag; break; case 4: *predictor = left+upper-diag; break; case 5: *predictor = left+((upper-diag)>>1); break; case 6: *predictor = upper+((left-diag)>>1); break; case 7: *predictor = (left+upper)>>1; break; default: fprintf(stderr,"Warning: Undefined PSV\n"); *predictor = 0; } } } } /* *-------------------------------------------------------------- * * QuickPredict -- * * Calculate the predictor for sample curRowBuf[col][curComp]. * It does not handle the special cases at image edges, such * as first row and first column of a scan. We put the special * case checkings outside so that the computations in main * loop can be simpler. This has enhenced the performance * significantly. * * Results: * predictor is passed out. * * Side effects: * None. * *-------------------------------------------------------------- */ void QuickPredict(col,curComp,curRowBuf,prevRowBuf,psv,predictor) int col; /* column # of the pixel to be predicted */ int curComp; /* the pixel's component that is predicting */ MCU *curRowBuf,*prevRowBuf; /* current and previous row of image */ int psv; /* predictor selection value */ int *predictor; /* preditor value (output) */ { register int left,upper,diag,leftcol; leftcol=col-1; upper=prevRowBuf[col][curComp]; left=curRowBuf[leftcol][curComp]; diag=prevRowBuf[leftcol][curComp]; /* * All predictor are calculated according to psv. */ switch (psv) { case 0: *predictor = 0; break; case 1: *predictor = left; break; case 2: *predictor = upper; break; case 3: *predictor = diag; break; case 4: *predictor = left+upper-diag; break; case 5: *predictor = left+((upper-diag)>>1); break; case 6: *predictor = upper+((left-diag)>>1); break; case 7: *predictor = (left+upper)>>1; break; default: fprintf(stderr,"Warning: Undefined PSV\n"); *predictor = 0; } } #endif /*DEBUG*/