📄 idwtmask.cpp
字号:
/* $Id: idwtmask.c,v 1.1 1999/02/18 21:18:58 shipeng Exp $ */
/****************************************************************************/
/* MPEG4 Visual Texture Coding (VTC) Mode Software */
/* */
/* This software was developed by */
/* Sarnoff Corporation and Texas Instruments */
/* Iraj Sodagar (iraj@sarnoff.com) Jie Liang (liang@ti.com) */
/* Hung-Ju Lee (hjlee@sarnoff.com) */
/* Paul Hatrack (hatrack@sarnoff.com) */
/* Shipeng Li (shipeng@sarnoff.com) */
/* Bing-Bing Chai (bchai@sarnoff.com) */
/* */
/* In the course of development of the MPEG-4 standard. This software */
/* module is an implementation of a part of one or more MPEG-4 tools as */
/* specified by the MPEG-4 standard. */
/* */
/* The copyright of this software belongs to ISO/IEC. ISO/IEC gives use */
/* of the MPEG-4 standard free license to use this software module or */
/* modifications thereof for hardware or software products claiming */
/* conformance to the MPEG-4 standard. */
/* */
/* Those intending to use this software module in hardware or software */
/* products are advised that use may infringe existing patents. The */
/* original developers of this software module and their companies, the */
/* subsequent editors and their companies, and ISO/IEC have no liability */
/* and ISO/IEC have no liability for use of this software module or */
/* modification thereof in an implementation. */
/* */
/* Permission is granted to MPEG memebers to use, copy, modify, */
/* and distribute the software modules ( or portions thereof ) */
/* for standardization activity within ISO/IEC JTC1/SC29/WG11. */
/* */
/* Copyright (C) 1998 Sarnoff Corporation and Texas Instruments */
/****************************************************************************/
/************************************************************/
/* Sarnoff Very Low Bit Rate Still Image Coder */
/* Copyright 1995, 1996, 1997, 1998 Sarnoff Corporation */
/************************************************************/
/* Inverse Mask DWT for MPEG-4 Still Texture Coding
Original Coded by Shipeng Li, Sarnoff Corporation, Jan. 1998*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "basic.hpp"
#include "dwt.h"
/* local prototypes */
/* Function: do_iDWTMask()
Description: Inverse DWT for MPEG-4 Still Texture Coding
Input:
InMask -- Input Mask for InCoeff, if ==1, data inside object,
otherwise outside.
Width -- Width of Original Image (must be multiples of 2^nLevels);
Height -- Height of Original Image (must be multiples of 2^nLevels);
CurLevel -- Currect Decomposition Level of the input wavelet mask;
DstLevel -- Destined decomposition level that the wavelet mask is
synthesized to. DstLevel always less than or equal to CurLevel;
Filter -- Filter Used.
UpdateInput -- Update the level of decomposition to DstLevel
for InMask or Not.
0 = No Update; 1 = Update and InMask;
Output:
OutMask -- Output mask
Return: DWT_OK if successful.
*/
Int VTCIDWTMASK::
do_iDWTMask(UChar *InMask, UChar *OutMask, Int Width, Int Height, Int CurLevel,
Int DstLevel, FILTER **Filter, Int UpdateInput, Int FullSizeOut)
{
Int i,level, k;
Int ret;
// UChar *c;
UChar *d,*e, *tempMask;
/* Check filter class first */
for(level=CurLevel;level>DstLevel; level--) {
if(Filter[level-1]->DWT_Class != DWT_ODD_SYMMETRIC && Filter[level-1]->DWT_Class != DWT_EVEN_SYMMETRIC ) {
return(DWT_FILTER_UNSUPPORTED);
}
}
/* Limit nLevels as: 0 - 15*/
if(DstLevel < 0 || CurLevel >=16 || DstLevel >=16 || DstLevel > CurLevel)
return(DWT_INVALID_LEVELS);
/* Check Width and Height, must be multiples of 2^CurLevel */
if( (Width & ((1<<CurLevel)-1)) !=0) return(DWT_INVALID_WIDTH);
if( (Height & ((1<<CurLevel)-1)) !=0) return(DWT_INVALID_HEIGHT);
/* copy mask */
tempMask = (UChar *)malloc(sizeof(UChar)*Width*Height);
if(tempMask==NULL) return(DWT_MEMORY_FAILED);
memcpy(tempMask, InMask, sizeof(UChar)*Width*Height);
/* Perform the iDWT */
for(level=CurLevel;level>DstLevel;level--) {
/* Synthesize one level */
ret=SynthesizeMaskOneLevel(tempMask, Width, Height,
level, Filter[level-1], DWT_NONZERO_HIGH);
if(ret!=DWT_OK) {
free(tempMask);
return(ret);
}
}
/* check to see if required to update InMask */
if(UpdateInput>0) {
/* Update InMask */
for(k=0;k<Width*(Height>>DstLevel); k+=Width) {
for(d=InMask+k,e=tempMask+k;d<InMask+k+(Width>>DstLevel);d++,e++) {
*d = *e;
}
}
}
if(FullSizeOut) {
/* Perform the rest of iDWT Mask till fullsize */
for(level=DstLevel;level>0;level--) {
/* Synthesize one level */
ret=SynthesizeMaskOneLevel(tempMask, Width, Height,
level, Filter[level-1], DWT_ZERO_HIGH);
if(ret!=DWT_OK) {
free(tempMask);
return(ret);
}
}
}
level=FullSizeOut?0:DstLevel;
for(i=0,k=0;k<Width*(Height >> level);k+=Width,i+=(Width>>level)) {
d = OutMask + i;
for(e=tempMask+k;e<tempMask+k+(Width>>level);e++,d++) *d=*e;
}
free(tempMask);
return(DWT_OK);
}
/* Function: SynthesizeMaskOneLevel()
Description: Synthesize one level of wavelet mask.
Input:
Width -- Width of Image;
Height -- Height of Image;
level -- current level
Filter -- Filter Used.
Input/Output:
OutMask -- Input/Output mask
Return: DWT_OK if successful.
*/
Int VTCIDWTMASK::
SynthesizeMaskOneLevel(UChar *OutMask, Int Width,
Int Height, Int level, FILTER *Filter, Int ZeroHigh)
{
UChar *InMaskBuf, *OutMaskBuf;
Int width = Width>>(level-1);
Int height = Height>>(level-1);
Int MaxLength = (width > height)?width:height;
Int i,k,ret;
UChar *c,*d;
InMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
OutMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
if(InMaskBuf ==NULL || OutMaskBuf==NULL)
return(DWT_MEMORY_FAILED);
if(ZeroHigh == DWT_ZERO_HIGH) {
for(i=0;i<(width>>1);i++) {
/* get a column of mask*/
for( c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+height; c+=2, d+=Width) {
*c = *(c+1) = *d;
}
for(c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+height; c++, d+=Width) {
*d = *c;
}
}
for(i=0;i<Width*height;i+=Width) {
for( c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+width; c+=2, d++) {
*c = *(c+1) = *d;
}
for(c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+width; c++, d++) {
*d = *c;
}
}
}
else {
/* vertical synthesis first */
for(i=0;i<width;i++) {
/* get a column of mask*/
for( c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+height; c++, d+=Width) {
*c = *d;
}
/* perform inverse vertical SA-DWT of Mask*/
ret=iSADWTMask1d(InMaskBuf, OutMaskBuf, height, Filter,
DWT_VERTICAL);
if(ret!=DWT_OK) {
free(InMaskBuf);free(OutMaskBuf);
return(ret);
}
/* put the transformed column back */
for(c= OutMaskBuf, d= OutMask+i;
c<OutMaskBuf+height; c++, d+=Width) {
*d = *c;
}
}
/* then horizontal synthesis */
for(i=0,k=0;i<height;i++,k+=Width) {
/* get a line of mask */
memcpy(InMaskBuf, OutMask+k, sizeof(UChar)*width);
/* Perform horizontal inverse SA-DWT */
ret=iSADWTMask1d(InMaskBuf, OutMaskBuf, width, Filter,
DWT_HORIZONTAL);
if(ret!=DWT_OK) {
free(InMaskBuf);free(OutMaskBuf);
return(ret);
}
/* put the transformed line back */
memcpy(OutMask+k, OutMaskBuf, sizeof(UChar)*width);
}
}
free(InMaskBuf);free(OutMaskBuf);
return(DWT_OK);
}
/* Function: SynthesizeMaskHalfLevel()
Description: Synthesize Half level of wavelet mask.
Input:
Width -- Width of Image;
Height -- Height of Image;
level -- current level
Filter -- Filter Used.
Direction -- VERTICAL or HORIZONTAL
Input/Output:
OutMask -- Input/Output mask
Return: DWT_OK if successful.
*/
Int VTCIDWTMASK::
SynthesizeMaskHalfLevel(UChar *OutMask, Int Width,
Int Height, Int level, FILTER *Filter,
Int ZeroHigh, Int Direction)
{
UChar *InMaskBuf, *OutMaskBuf;
Int width = Width>>(level-1);
Int height = Height>>(level-1);
Int MaxLength = (width > height)?width:height;
Int i,k,ret;
UChar *c,*d;
InMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
OutMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
if(InMaskBuf ==NULL || OutMaskBuf==NULL)
return(DWT_MEMORY_FAILED);
if(ZeroHigh == DWT_ZERO_HIGH) {
if(Direction == DWT_VERTICAL) {
for(i=0;i<(width>>1);i++) {
/* get a column of mask*/
for( c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+height; c+=2, d+=Width) {
*c = *(c+1) = *d;
}
for(c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+height; c++, d+=Width) {
*d = *c;
}
}
}
else {
for(i=0;i<Width*height;i+=Width) {
for( c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+width; c+=2, d++) {
*c = *(c+1) = *d;
}
for(c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+width; c++, d++) {
*d = *c;
}
}
}
}
else {
if(Direction==DWT_VERTICAL) {
/* vertical synthesis first */
for(i=0;i<width;i++) {
/* get a column of mask*/
for( c= InMaskBuf, d= OutMask+i;
c<InMaskBuf+height; c++, d+=Width) {
*c = *d;
}
/* perform inverse vertical SA-DWT of Mask*/
ret=iSADWTMask1d(InMaskBuf, OutMaskBuf, height, Filter,
DWT_VERTICAL);
if(ret!=DWT_OK) {
free(InMaskBuf);free(OutMaskBuf);
return(ret);
}
/* put the transformed column back */
for(c= OutMaskBuf, d= OutMask+i;
c<OutMaskBuf+height; c++, d+=Width) {
*d = *c;
}
}
}
else {
/* then horizontal synthesis */
for(i=0,k=0;i<height;i++,k+=Width) {
/* get a line of mask */
memcpy(InMaskBuf, OutMask+k, sizeof(UChar)*width);
/* Perform horizontal inverse SA-DWT */
ret=iSADWTMask1d(InMaskBuf, OutMaskBuf, width, Filter,
DWT_HORIZONTAL);
if(ret!=DWT_OK) {
free(InMaskBuf);free(OutMaskBuf);
return(ret);
}
/* put the transformed line back */
memcpy(OutMask+k, OutMaskBuf, sizeof(UChar)*width);
}
}
}
free(InMaskBuf);free(OutMaskBuf);
return(DWT_OK);
}
/* Function: iSADWTMask1d()
Description: inverse 1-d SA-DWT of Mask
Input:
InMaskBuf -- Input 1d mask buffer
Length -- length of the input data
Filter -- filter used
Direction -- vertical or horizontal synthesis (used for inversible
mask synthsis)
Output:
OutMask -- Mask for the synthesized 1d Data
Return: return DWT_OK if successful
*/
Int VTCIDWTMASK::
iSADWTMask1d(UChar *InMaskBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
{
switch(Filter->DWT_Class){
case DWT_ODD_SYMMETRIC:
return(iSADWTMask1dOddSym(InMaskBuf, OutMaskBuf,
Length, Filter, Direction));
case DWT_EVEN_SYMMETRIC:
return(iSADWTMask1dEvenSym(InMaskBuf, OutMaskBuf,
Length, Filter, Direction));
default:
return(DWT_FILTER_UNSUPPORTED);
}
}
/* Function: iSADWTMask1dOddSym()
Description: 1D iSA-DWT of Mask using Odd Symmetric Filter
Input:
InMaskBuf -- Input 1d mask buffer
Length -- length of the input data
Filter -- filter used
Direction -- vertical or horizontal synthesis (used for inversible
mask synthesis)
Output:
OutMask -- Synthesized 1d Mask
Return: return DWT_OK if successful
*/
Int VTCIDWTMASK::
iSADWTMask1dOddSym(UChar *InMaskBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
{
// Int i;
Int SegLength = 0;
// Int odd;
// Int start, even, end;
UChar *a, *b, *c;
// Int ret;
/* double check filter class and type */
if(Filter->DWT_Class != DWT_ODD_SYMMETRIC) return(DWT_INTERNAL_ERROR);
/* double check if Length is even */
if(Length & 1) return(DWT_INTERNAL_ERROR);
/* synthesize mask first */
for(a=OutMaskBuf, b = InMaskBuf, c= InMaskBuf+(Length>>1); a<OutMaskBuf+Length;b++,c++) {
if(Direction == DWT_VERTICAL) {
if(*c == DWT_OUT2) {
*a++=DWT_OUT0;
*a++=DWT_IN;
}
else if(*c == DWT_OUT3) {
*a++=DWT_OUT1;
*a++=DWT_IN;
}
else {
*a++=*b;
*a++=*c;
}
}
else {
if(*c == DWT_OUT1) {
*a++=DWT_OUT0;
*a++=DWT_IN;
}
else {
*a++ = *b;
*a++ = *c;
}
}
}
return(DWT_OK);
}
Int VTCIDWTMASK::
iSADWTMask1dEvenSym(UChar *InMaskBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
{
//Int i;
Int SegLength = 0;
// Int odd;
// Int start, even, end;
UChar *a, *b, *c;
// Int ret;
/* double check filter class and type */
if(Filter->DWT_Class != DWT_EVEN_SYMMETRIC) return(DWT_INTERNAL_ERROR);
/* double check if Length is even */
if(Length & 1) return(DWT_INTERNAL_ERROR);
/* synthesize mask first */
for(a=OutMaskBuf, b = InMaskBuf, c= InMaskBuf+(Length>>1); a<OutMaskBuf+Length;b++,c++) {
if(Direction == DWT_VERTICAL) {
if(*c == DWT_OUT2) {
*a++=DWT_OUT0;
*a++=DWT_IN;
}
else if(*c == DWT_OUT3) {
*a++=DWT_OUT1;
*a++=DWT_IN;
}
else {
*a++=*b;
*a++=*c;
}
}
else {
if(*c == DWT_OUT1) {
*a++=DWT_OUT0;
*a++=DWT_IN;
}
else {
*a++ = *b;
*a++ = *c;
}
}
}
return(DWT_OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -