/* File: sv_h263_mres.c */ /***************************************************************************** ** Copyright (c) Digital Equipment Corporation, 1995, 1997 ** ** ** ** All Rights Reserved. Unpublished rights reserved under the copyright ** ** laws of the United States. ** ** ** ** The software contained on this media is proprietary to and embodies ** ** the confidential technology of Digital Equipment Corporation. ** ** Possession, use, duplication or dissemination of the software and ** ** media is authorized only pursuant to a valid written license from ** ** Digital Equipment Corporation. ** ** ** ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. ** ** Government is subject to restrictions as set forth in Subparagraph ** ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. ** ******************************************************************************/ #include "sv_h263.h" #include "proto.h" static void hfilt121(unsigned char *img, unsigned char *filtd, unsigned char s, unsigned char gain, int rows, int cols) ; static void hfilt5(unsigned char *img, unsigned char *filtd, unsigned char s, unsigned char gain, int rows, int cols) ; static void vfilt121(unsigned char *img, unsigned char *filtd, unsigned char s, unsigned char gain, int rows, int cols) ; static void vfilt5(unsigned char *img, unsigned char *filtd, unsigned char s, unsigned char gain, int rows, int cols) ; static void lowpass(unsigned char *img, unsigned char *lp, int rows, int cols, int ntaps) ; static void reduce(unsigned char *img, unsigned char *red, int rows, int cols, int ntaps) ; static void hpad(unsigned char *img, unsigned char *zp, unsigned char s, int rows, int cols, char mode) ; static void Expand(unsigned char *img, unsigned char *exp, int rows, int cols, char mode, int ntaps) ; static void gaussp(unsigned char *img, unsigned char **pyr, int depth, int rows, int cols, int ntaps) ; static unsigned char **palloc(int depth, int rows, int cols) ; static H263_PictImage **PictPyr(H263_PictImage *img, int depth, int rows, int cols, int ntaps); static void expyr(unsigned char **pyr, unsigned char **filtd, int depth, int rows, int cols, char mode, int ntaps); static H263_PictImage **GaussFilt(H263_PictImage *img, int depth, int rows, int cols, int ntaps); /****************************************************************** * Function hfilt121 * Filters img horizontally with a 1:2:1 filter, subsampling by s. * rows, cols are the dimensions of img *****************************************************************/ static void hfilt121(unsigned char *img, unsigned char *filtd, unsigned char s, unsigned char gain, int rows, int cols) { unsigned char *pimg, *pf; float conv, tmp; int i, j; pf = filtd; pimg = img; for(i=0; i 255 ? 255 : conv); *(pf++) = (unsigned char) (tmp < 0 ? 0 : tmp); pimg+=s; /* Do line */ for(j=s; j 255 ? 255 : conv); *(pf++) = (unsigned char)(tmp < 0 ? 0 : tmp); } /* Do last pixel if s equals one */ if(s==1) { conv = (float)gain * ((float)*pimg * (float)2.0 + (float)*(pimg-1) * (float)2.0) / (float)4.0; tmp = (conv > 255 ? 255 : conv); *(pf++) = (unsigned char)(tmp < 0 ? 0 : tmp); pimg+=s; } } } /****************************************************************** * Function hfilt5 * Filters img horizontally with a 5 tap gaussian filter, subsampling by s. * rows, cols are the dimensions of img *****************************************************************/ static void hfilt5(unsigned char *img, unsigned char *filtd, unsigned char s, unsigned char gain, int rows, int cols) { unsigned char *pimg, *pf; float conv, tmp; int i, j; pf = filtd; pimg = img; for(i=0; i 255 ? 255 : conv); *(pf++) = (unsigned char)(tmp < 0 ? 0 : tmp); } } } /****************************************************************** * Function vfilt121 * Filters img vertically with a 1:2:1 filter, subsampling by s. * rows, cols are the dimensions of img *****************************************************************/ static void vfilt121(unsigned char *img, unsigned char *filtd, unsigned char s, unsigned char gain, int rows, int cols) { unsigned char *pimg, *pf; float tmp, conv; int i, j; pf = filtd; pimg = img; /* Do first line */ for(j=0; j 255 ? 255 : conv); *(pf++) = (unsigned char)(tmp < 0 ? 0 : tmp); } pimg+= (s-1)*cols; /* Do image center */ for(i=s; i 255 ? 255 : conv); *(pf++) = (unsigned char)(tmp < 0 ? 0 : tmp); } pimg+=(s-1)*cols; } /* Do last line if s equals one */ if(s==1) { for(j=0; j 255 ? 255 : conv); *(pf++) = (unsigned char)(tmp < 0 ? 0 : tmp); } } } /****************************************************************** * Function vfilt5 * Filters img vertically with a 5 tap gaussian filter, subsampling by s. * rows, cols are the dimensions of img *****************************************************************/ static void vfilt5(unsigned char *img, unsigned char *filtd, unsigned char s, unsigned char gain, int rows, int cols) { unsigned char *pimg, *pf; float conv, tmp; int i, j, tcols; pf = filtd; pimg = img; tcols = 2*cols; for(i=0; i 255 ? 255 : conv); *(pf++) = (unsigned char)(tmp < 0 ? 0 : tmp); } pimg+=(s-1)*cols; } } /****************************************************************** * Function lowpass * 2D low pass filtering of img into lp. rows, * cols are the dimensions of img. ******************************************************************/ static void lowpass(unsigned char *img, unsigned char *lp, int rows, int cols, int ntaps) { unsigned char *tmp; if (!(tmp = (unsigned char *)ScAlloc(rows*cols))) { /* fprintf(stderr,"ScAlloc failed\n"); exit(-1); */ return; } switch (ntaps) { case 3: hfilt121(img, tmp, 1, 1, rows, cols); vfilt121(tmp, lp, 1, 1, rows, cols); break; case 5: hfilt5(img, tmp, 1, 1, rows, cols); vfilt5(tmp, lp, 1, 1, rows, cols); break; default: /* printf("Unknown filter in lowpass\n"); exit(0); */ ScFree(tmp); return; } ScFree(tmp); } /****************************************************************** * Function reduce * 2D low pass filtering and subsampling by two of img into red. rows, * cols are the dimensions of img. ******************************************************************/ static void reduce(unsigned char *img, unsigned char *red, int rows, int cols, int ntaps) { unsigned char *tmp; if (!(tmp = (unsigned char *)ScAlloc(rows*cols/2))) { /* fprintf(stderr,"ScAlloc failed\n"); exit(-1); */ return; } switch (ntaps) { case 3: hfilt121(img, tmp, 2, 1, rows, cols); vfilt121(tmp, red, 2, 1, rows, cols>>1); break; case 5: hfilt5(img, tmp, 2, 1, rows, cols); vfilt5(tmp, red, 2, 1, rows, cols>>1); break; default: /* printf("Unknown filter in reduce\n"); exit(0); */ ScFree(tmp); return; } ScFree(tmp); } /****************************************************************** * Function hpad * Zero-pads img horizontaly by the factor s. Returns zero-paded * image in zp. rows, cols are the dimensions of img *****************************************************************/ static void hpad(unsigned char *img, unsigned char *zp, unsigned char s, int rows, int cols, char mode) { int i, j; unsigned char *pf, *pimg, fill; switch (mode) { case 'l': fill = 0; break; case 'c': fill = 0; break; default: /* printf("Unknown fill mode in hpad\n"); exit(0); */ return; } pimg = img; pf = zp; for(i=0; ilum, tmp, depth, rows, cols, ntaps); for(d=0; dlum = tmp[d]; rows/=2; cols/=2; /* Chroma 1 */ tmp = palloc(depth, rows, cols); gaussp(img->Cr, tmp, depth, rows, cols, ntaps); for(d=0; dCr = tmp[d]; /* Chroma 2 */ tmp = palloc(depth, rows, cols); gaussp(img->Cb, tmp, depth, rows, cols, ntaps); for(d=0; dCb = tmp[d]; ScFree(tmp); return PictPyr; } /***************************************************************** * Function expyr * Expands the pyramid channels to full resolution. rows, cols * are the dimensions of the expanded images, and the full resolution * layer of the pyramid. *****************************************************************/ static void expyr(unsigned char **pyr, unsigned char **filtd, int depth, int rows, int cols, char mode, int ntaps) { int d, l, r, c; r = rows; c = cols; memcpy(filtd[0], pyr[0], rows*cols); for(d=1; d0; l--) Expand(pyr[d], pyr[d-1], r, c, mode, ntaps); memcpy(filtd[d], pyr[0], rows*cols); } } /***************************************************************** * Function GaussFilt * Builds an array of successively more low pass filtered images * by constructing a gaussian pyramid and expanding each level * to full resolution *****************************************************************/ static H263_PictImage **GaussFilt(H263_PictImage *img, int depth, int rows, int cols, int ntaps) { int d; H263_PictImage **PictFiltd; unsigned char **tmp, **filtd; PictFiltd = (H263_PictImage **) ScAlloc(depth*sizeof(H263_PictImage *)); for(d=0; dlum, tmp, depth, rows, cols, ntaps); expyr(tmp, filtd, depth, rows, cols, 'l', ntaps); for(d=0; dlum, filtd[d], rows*cols); for(d=0; dCr, tmp, depth, rows, cols, ntaps); expyr(tmp, filtd, depth, rows, cols, 'c', ntaps); for(d=0; dCr, filtd[d], rows*cols); for(d=0; dCb, tmp, depth, rows, cols, ntaps); expyr(tmp, filtd, depth, rows, cols, 'c', ntaps); for(d=0; dCb, filtd[d], rows*cols); for(d=0; dlum, img->lum, rows*cols); for(d=1; dlum, PictFiltd[d]->lum, rows, cols, ntaps); rows/=2; cols/=2; /* Chroma 1 */ memcpy(PictFiltd[0]->Cr, img->Cr, rows*cols); for(d=1; dCr, PictFiltd[d]->Cr, rows, cols, ntaps); /* Chroma 2 */ memcpy(PictFiltd[0]->Cb, img->Cb, rows*cols); for(d=1; dCb, PictFiltd[d]->Cb, rows, cols, ntaps); return PictFiltd; }