/* File: sv_h263_morph.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. ** ******************************************************************************/ /* #define _SLIBDEBUG_ */ #include "sv_h263.h" #include "proto.h" #ifdef _SLIBDEBUG_ #include "sc_debug.h" #define _DEBUG_ 0 /* detailed debuging statements */ #define _VERBOSE_ 1 /* show progress */ #define _VERIFY_ 0 /* verify correct operation */ #define _WARN_ 1 /* warnings about strange behavior */ #endif static unsigned char min5(unsigned char a, unsigned char b, unsigned char c, unsigned char d, unsigned char e) ; static unsigned char max5(unsigned char a, unsigned char b, unsigned char c, unsigned char d, unsigned char e) ; static void ErodeX(unsigned char *image, unsigned char *out, int rows, int cols); static void DilateX(unsigned char *image, unsigned char *out, int rows, int cols); static void ErodeS(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc); static void DilateS(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc); static void Dilate(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc); static void Erode(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc); static void Open(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc); static void EdgeSelect(H263_PictImage *input, H263_PictImage *filtd, unsigned char *edge, H263_PictImage *output, int rows, int cols) ; /***************************************************************************************************** * Function min5 * Computes the min of the five elements ****************************************************************************************************/ static unsigned char min5(unsigned char a, unsigned char b, unsigned char c, unsigned char d, unsigned char e) { unsigned char out; out = a; if(bout) out=b; if(c>out) out=c; if(d>out) out=d; if(e>out) out=e; return out; } /***************************************************************************************************** * Function: ErodeX * Erosion of image (dimensions rows, cols) by a "+" structuring element ****************************************************************************************************/ static void ErodeX(unsigned char *image, unsigned char *out, int rows, int cols) { int i, j; unsigned char *pi, *po; pi = image; po = out; /**** First line ****/ /* First pixel */ *po = min5(*pi, *pi, *(pi+1), *pi, *(pi+cols)); pi++; po++; /* Center pixels */ for(j=1; j> 1; sc2 = sc >> 1; pi = image; po = out; for(i=0; isr2 ? sr2 : i; dl = j > sc2 ? sc2 : j; if(odd) { db = (rows-1-i) > sr2 ? sr2 : (rows-1-i); dr = (cols-1-j) > sc2 ? sc2 : (cols-1-j); } else { db = (rows-1-i) > sr2-1 ? sr2-1 : (rows-1-i); dr = (cols-1-j) > sc2-1 ? sc2-1 : (cols-1-j); } min = 255; for(k=-du; k<=db; k++) { pse = pi + k * cols - dl; for(l=-dl; l<=dr; l++, pse++) { min = *pse < min ? *pse : min; } } *po = min; } } } /***************************************************************************************************** * Function: DilateS * Dilation of image (dimensions rows, cols) by a square structuring element of dimensions (sr, sc) ****************************************************************************************************/ static void DilateS(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc) { int i, j, k, l, du, db, dl, dr, sr2, sc2; unsigned char *pi, *po, *pse, max, odd; odd = 1; if (!(sr%2) || !(sc%2)) odd = 0; sr2 = sr >> 1; sc2 = sc >> 1; pi = image; po = out; for(i=0; isr2 ? sr2 : i; dl = j > sc2 ? sc2 : j; if(odd) { db = (rows-1-i) > sr2 ? sr2 : (rows-1-i); dr = (cols-1-j) > sc2 ? sc2 : (cols-1-j); } else { db = (rows-1-i) > sr2-1 ? sr2-1 : (rows-1-i); dr = (cols-1-j) > sc2-1 ? sc2-1 : (cols-1-j); } max = 0; for(k=-du; k<=db; k++) { for(l=-dl; l<=dr; l++, pse++) { pse = pi + k * cols + l; max = (*pse > max) ? *pse : max; } } *po = max; } } } /***************************************************************************************************** * Function: Dilate * Dilation of image (dimensions rows, cols) by a structuring element of dimensions (sr, sc). * If (sr, sc) are positive the structuring element is positive. If they are -1 it is * the cross '+' ****************************************************************************************************/ static void Dilate(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc) { if(sr > 0 && sc > 0) { DilateS(image, out, rows, cols, sr, sc); } else if(sr==-1 && sc ==-1) { DilateX(image, out, rows, cols); } else { _SlibDebug(_WARN_, printf("Dilate() Unknown structuring element\n") ); return; } } /***************************************************************************************************** * Function: Erode * Erosion of image (dimensions rows, cols) by a structuring element of dimensions (sr, sc). * If (sr, sc) are positive the structuring element is positive. If they are -1 it is * the cross '+' ****************************************************************************************************/ static void Erode(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc) { if(sr > 0 && sc > 0) { ErodeS(image, out, rows, cols, sr, sc); } else if(sr==-1 && sc ==-1) { ErodeX(image, out, rows, cols); } else { _SlibDebug(_WARN_, printf("Erode() Unknown structuring element\n") ); return; } } /***************************************************************************************************** * Function: Open * Opening of image (dimensions rows, cols) by a square structuring element of dimensions (sr, sc) ****************************************************************************************************/ static void Open(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc) { unsigned char *tmp; if (!(tmp = (unsigned char *)ScAlloc(rows*cols))) { _SlibDebug(_WARN_, printf("Open() ScAlloc failed\n") ); return; } Erode(image, tmp, rows, cols, sr, sc); Dilate(tmp, out, rows, cols, sr, sc); ScFree(tmp); } /***************************************************************************************************** * Function: Close * Closing of image (dimensions rows, cols) by a square structuring element of dimensions (sr, sc) ****************************************************************************************************/ void Close(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc) { unsigned char *tmp; if (!(tmp = (unsigned char *)ScAlloc(rows*cols))) { _SlibDebug(_WARN_, printf("Close() ScAlloc failed\n") ); return; } Dilate(image, tmp, rows, cols, sr, sc); Erode(tmp, out, rows, cols, sr, sc); ScFree(tmp); } /***************************************************************************************************** * Function: OpenClose * Open/Closing of image (dimensions rows, cols) by a square structuring element of dimensions (sr, sc) ****************************************************************************************************/ void OpenClose(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc) { unsigned char *tmp; if (!(tmp = (unsigned char *)ScAlloc(rows*cols))) { _SlibDebug(_WARN_, printf("OpenClose() ScAlloc failed\n") ); return; } Open(image, tmp, rows, cols, sr, sc); Close(tmp, out, rows, cols, sr, sc); ScFree(tmp); } /***************************************************************************************************** * Function: CloseOpen * Open/Closing of image (dimensions rows, cols) by a square structuring element of dimensions (sr, sc) ****************************************************************************************************/ void CloseOpen(unsigned char *image, unsigned char *out, int rows, int cols, int sr, int sc) { unsigned char *tmp; if (!(tmp = (unsigned char *)ScAlloc(rows*cols))) { _SlibDebug(_WARN_, printf("CloseOpen() ScAlloc failed\n") ); return; } Close(image, tmp, rows, cols, sr, sc); Open(tmp, out, rows, cols, sr, sc); ScFree(tmp); } /***************************************************************************************************** * Function: GeoDilate * Geodesic dilation of size one of image with respect to reference ****************************************************************************************************/ void GeoDilate(unsigned char *image, unsigned char *reference, int rows, int cols, int sr, int sc) { int i, j; unsigned char *pi, *pr, *pt, *tmp; if (!(tmp = (unsigned char *)ScAlloc(rows*cols))) { _SlibDebug(_WARN_, printf("GeoDilate() ScAlloc failed\n") ); return; } Dilate(image, tmp, rows, cols, sr, sc); pi = image; pr = reference; pt = tmp; for(i=0; ilum; pf = filtd->lum; po = output->lum; pe = edge; for(i=0; iCr; pf = filtd->Cr; po = output->Cr; pe = edge; for(i=0; iCb; pf = filtd->Cb; po = output->Cb; pe = edge; for(i=0; ilum, Edge, Orient, rows, cols); morph = sv_H263InitImage(H263Info->pels*H263Info->lines); OpenCloseRec(H263Info->curr_image->lum, morph->lum, rows, cols, sr, sc); OpenCloseRec(H263Info->curr_image->Cr, morph->Cr, rows >> 1, cols >> 1, sr, sc); OpenCloseRec(H263Info->curr_image->Cb, morph->Cb, rows >> 1, cols >> 1, sr, sc); clean = sv_H263InitImage(rows*cols); if (!(CleanEmap = (unsigned char *)ScAlloc(rows*cols))) { _SlibDebug(_WARN_, printf("PredOpenCloseRec() ScAlloc failed\n") ); return(NULL); } CloseOpen(Edge, CleanEmap, rows, cols, sr, sc); EdgeSelect(H263Info->curr_image, morph, CleanEmap, clean, rows, cols); sv_H263FreeImage(morph); ScFree(CleanEmap); ScFree(Orient); ScFree(Edge); return clean; } /***************************************************************** * Function MorphLayers * Builds an array of successively more morphologically low pass * filtered images. sz is the size of the structuring element (-1 for * the cross '+'). *****************************************************************/ H263_PictImage **sv_H263MorphLayers(H263_PictImage *img, int depth, int rows, int cols, int sz) { int d; H263_PictImage **PictFiltd; PictFiltd = (H263_PictImage **) ScAlloc(depth*sizeof(H263_PictImage *)); for(d=0; dlum, img->lum, rows*cols); for(d=1; dlum, PictFiltd[d]->lum, rows, cols, sz, sz); rows/=2; cols/=2; /* Chroma 1 */ memcpy(PictFiltd[0]->Cr, img->Cr, rows*cols); for(d=1; dCr, PictFiltd[d]->Cr, rows, cols, sz, sz); /* Chroma 2 */ memcpy(PictFiltd[0]->Cb, img->Cb, rows*cols); for(d=1; dCb, PictFiltd[d]->Cb, rows, cols, sz, sz); return PictFiltd; }