📄 dwt_aux.cpp
字号:
/* $Id: dwt_aux.c,v 1.11 1998/05/19 15:48:03 hjlee Exp $ */
/****************************************************************************/
/* MPEG4 Visual Texture Coding (VTC) Mode Software */
/* */
/* This software was jointly developed by the following participants: */
/* */
/* Single-quant, multi-quant and flow control */
/* are provided by Sarnoff Corporation */
/* Iraj Sodagar (iraj@sarnoff.com) */
/* Hung-Ju Lee (hjlee@sarnoff.com) */
/* Paul Hatrack (hatrack@sarnoff.com) */
/* Shipeng Li (shipeng@sarnoff.com) */
/* Bing-Bing Chai (bchai@sarnoff.com) */
/* B.S. Srinivas (bsrinivas@sarnoff.com) */
/* */
/* Bi-level is provided by Texas Instruments */
/* Jie Liang (liang@ti.com) */
/* */
/* Shape Coding is provided by OKI Electric Industry Co., Ltd. */
/* Zhixiong Wu (sgo@hlabs.oki.co.jp) */
/* Yoshihiro Ueda (yueda@hlabs.oki.co.jp) */
/* Toshifumi Kanamaru (kanamaru@hlabs.oki.co.jp) */
/* */
/* OKI, Sharp, Sarnoff, TI and Microsoft contributed to bitstream */
/* exchange and bug fixing. */
/* */
/* */
/* 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 members to use, copy, modify, */
/* and distribute the software modules ( or portions thereof ) */
/* for standardization activity within ISO/IEC JTC1/SC29/WG11. */
/* */
/* Copyright 1995, 1996, 1997, 1998 ISO/IEC */
/****************************************************************************/
/************************************************************/
/* Sarnoff Very Low Bit Rate Still Image Coder */
/* Copyright 1995, 1996, 1997, 1998 Sarnoff Corporation */
/************************************************************/
#ifndef _DWT_DBL_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <memory.h>
#include "basic.hpp"
#include "dwt.h"
#define _DWT_INT_
#endif /* _DWT_DBL_ */
#undef DWTDATA
#ifdef _DWT_INT_
#define DWTDATA Int
#else
#define DWTDATA double
#endif
#ifdef _DWT_INT_
/* Function: DecomposeOneLevelInt()
Description: Pyramid Decompose one level of wavelet coefficients
Input:
Width -- Width of Image;
Height -- Height of Image;
level -- current decomposition level
Filter -- Filter Used.
MaxCoeff, MinCoeff -- bounds of the output data;
Input/Output:
OutCoeff -- Ouput wavelet coefficients
OutMask -- Output mask corresponding to wavelet coefficients
Return: DWT_OK if success.
*/
Int VTCDWT:: DecomposeOneLevelInt(Int *OutCoeff, UChar *OutMask, Int Width,
Int Height, Int level, FILTER *Filter,
Int MaxCoeff, Int MinCoeff)
{
Int *InBuf, *OutBuf ;
UChar *InMaskBuf, *OutMaskBuf;
Int width = Width>>(level-1);
Int height = Height>>(level-1);
Int MaxLength = (width > height)?width:height;
Int i,k,ret;
Int *a;
UChar *c,*d;
Int *e;
/* double check filter type */
if(Filter->DWT_Type != DWT_INT_TYPE) return(DWT_INTERNAL_ERROR);
/* allocate line buffers */
InBuf = (Int *) malloc(sizeof(Int)*MaxLength);
InMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
OutBuf = (Int *) malloc(sizeof(Int)*MaxLength);
OutMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
if(InBuf==NULL || InMaskBuf ==NULL || OutBuf == NULL || OutMaskBuf==NULL)
return(DWT_MEMORY_FAILED);
/* horizontal decomposition first*/
for(i=0,k=0;i<height;i++,k+=Width) {
/* get a line of coefficients */
for(a=InBuf, e=OutCoeff+k;a<InBuf+width;a++,e++) {
*a = (Int) *e;
}
/* get a line of mask */
memcpy(InMaskBuf, OutMask+k, sizeof(UChar)*width);
/* Perform horizontal SA-DWT */
ret=SADWT1dInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf, width, Filter,
DWT_HORIZONTAL);
if(ret!=DWT_OK) {
free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
return(ret);
}
/* put the transformed line back */
for(a=OutBuf,e=OutCoeff+k;a<OutBuf+width;a++,e++) {
/* Scale and Leave 3 extra bits for precision reason */
*a = ROUNDDIV((*a <<3), Filter->Scale);
if(*a > MaxCoeff || *a < MinCoeff) {
free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
return(DWT_COEFF_OVERFLOW);
}
*e = (Int) *a;
}
memcpy(OutMask+k, OutMaskBuf, sizeof(UChar)*width);
}
/* then vertical decomposition */
for(i=0;i<width;i++) {
/* get a column of coefficients */
for(a=InBuf, e=OutCoeff+i, c= InMaskBuf, d= OutMask+i;
a<InBuf+height; a++, c++, e+=Width, d+=Width) {
*a=(Int) *e;
*c = *d;
}
/* perform vertical SA-DWT */
ret=SADWT1dInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf, height, Filter,
DWT_VERTICAL);
if(ret!=DWT_OK) {
free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
return(ret);
}
/* put the transformed column back */
for(a=OutBuf, e=OutCoeff+i, c= OutMaskBuf, d= OutMask+i;
a<OutBuf+height; a++, c++, e+=Width, d+=Width) {
/*Scale and leave the sqrt(2)*sqrt(2) factor in the scale */
*a = ROUNDDIV(*a, (Filter->Scale<<2));
if(*a > MaxCoeff || *a < MinCoeff) {
free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
return(DWT_COEFF_OVERFLOW);
}
*e= (Int) *a;
*d = *c;
}
}
free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
return(DWT_OK);
}
#else
/* Function: DecomposeOneLevelDbl()
Description: Pyramid Decompose one level of wavelet coefficients
Input:
Width -- Width of Image;
Height -- Height of Image;
level -- current decomposition level
Filter -- Filter Used.
MaxCoeff, MinCoeff -- bounds of the output data;
Input/Output:
OutCoeff -- Ouput wavelet coefficients
OutMask -- Output mask corresponding to wavelet coefficients
Return: DWT_OK if success.
*/
Int VTCDWT:: DecomposeOneLevelDbl(double *OutCoeff, UChar *OutMask, Int Width,
Int Height, Int level, FILTER *Filter)
{
double *InBuf, *OutBuf ;
UChar *InMaskBuf, *OutMaskBuf;
Int width = Width>>(level-1);
Int height = Height>>(level-1);
Int MaxLength = (width > height)?width:height;
Int i,k,ret;
double *a;
UChar *c,*d;
double *e;
/* double check filter type */
if(Filter->DWT_Type != DWT_DBL_TYPE) return(DWT_INTERNAL_ERROR);
/* allocate line buffers */
InBuf = (double *) malloc(sizeof(double)*MaxLength);
InMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
OutBuf = (double *) malloc(sizeof(double)*MaxLength);
OutMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
if(InBuf==NULL || InMaskBuf ==NULL || OutBuf == NULL || OutMaskBuf==NULL)
return(DWT_MEMORY_FAILED);
/* horizontal decomposition first*/
for(i=0,k=0;i<height;i++,k+=Width) {
/* get a line of coefficients */
for(a=InBuf, e=OutCoeff+k;a<InBuf+width;a++,e++) {
*a = *e;
}
/* get a line of mask */
memcpy(InMaskBuf, OutMask+k, sizeof(UChar)*width);
/* Perform horizontal SA-DWT */
ret=SADWT1dDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf, width, Filter,
DWT_HORIZONTAL);
if(ret!=DWT_OK) {
free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
return(ret);
}
/* put the transformed line back */
for(a=OutBuf,e=OutCoeff+k;a<OutBuf+width;a++,e++) {
*e = *a;
}
memcpy(OutMask+k, OutMaskBuf, sizeof(UChar)*width);
}
/* then vertical decomposition */
for(i=0;i<width;i++) {
/* get a column of coefficients */
for(a=InBuf, e=OutCoeff+i, c= InMaskBuf, d= OutMask+i;
a<InBuf+height; a++, c++, e+=Width, d+=Width) {
*a = *e;
*c = *d;
}
/* perform vertical SA-DWT */
ret=SADWT1dDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf, height, Filter,
DWT_VERTICAL);
if(ret!=DWT_OK) {
free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
return(ret);
}
/* put the transformed column back */
for(a=OutBuf, e=OutCoeff+i, c= OutMaskBuf, d= OutMask+i;
a<OutBuf+height; a++, c++, e+=Width, d+=Width) {
*e = *a;
*d = *c;
}
}
free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
return(DWT_OK);
}
#endif
/* Function: SADWT1dInt() or SADWT1dDbl()
Description: 1-d SA-DWT
Input:
InBuf -- Input 1d data buffer
InMaskBuf -- Input 1d mask buffer
Length -- length of the input data
Filter -- filter used
Direction -- vertical or horizontal decomposition (used for inversible
mask decomposition)
Output:
OutBuf -- Transformed 1d Data
OutMask -- Mask for the Transformed 1d Data
Return: return DWT_OK if successful
*/
#ifdef _DWT_INT_
Int VTCDWT:: SADWT1dInt(Int *InBuf, UChar *InMaskBuf, Int *OutBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
{
switch(Filter->DWT_Class){
case DWT_ODD_SYMMETRIC:
return(SADWT1dOddSymInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf,
Length, Filter, Direction));
case DWT_EVEN_SYMMETRIC:
return(SADWT1dEvenSymInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf,
Length, Filter, Direction));
/* case ORTHOGONAL:
return(SADWT1dOrthInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf,
Length, Filter, Direction)); */
default:
return(DWT_FILTER_UNSUPPORTED);
}
}
#else
Int VTCDWT:: SADWT1dDbl(double *InBuf, UChar *InMaskBuf, double *OutBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
{
switch(Filter->DWT_Class){
case DWT_ODD_SYMMETRIC:
return(SADWT1dOddSymDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf,
Length, Filter, Direction));
case DWT_EVEN_SYMMETRIC:
return(SADWT1dEvenSymDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf,
Length, Filter, Direction));
/* case ORTHOGONAL:
return(SADWT1dOrthDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf,
Length, Filter, Direction)); */
default:
return(DWT_FILTER_UNSUPPORTED);
}
}
#endif
/* Function: SADWT1dOddSymInt() or SADWT1dOddSymDbl()
Description: 1D SA-DWT using Odd Symmetric Filter
Input:
InBuf -- Input 1d data buffer
InMaskBuf -- Input 1d mask buffer
Length -- length of the input data
Filter -- filter used
Direction -- vertical or horizontal decomposition (used for inversible
mask decomposition)
Output:
OutBuf -- Transformed 1d Data
OutMask -- Mask for the Transformed 1d Data
Return: return DWT_OK if successful
*/
#ifdef _DWT_INT_
Int VTCDWT:: SADWT1dOddSymInt(DWTDATA *InBuf, UChar *InMaskBuf, DWTDATA *OutBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
#else
Int VTCDWT:: SADWT1dOddSymDbl(DWTDATA *InBuf, UChar *InMaskBuf, DWTDATA *OutBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
#endif
{
Int i;
Int SegLength = 0;
Int odd;
Int start, end;
UChar *a, *b, *c;
Int ret;
/* double check filter class and type */
if(Filter->DWT_Class != DWT_ODD_SYMMETRIC) return(DWT_INTERNAL_ERROR);
#ifdef _DWT_INT_
if(Filter->DWT_Type != DWT_INT_TYPE) return(DWT_INTERNAL_ERROR);
#else
if(Filter->DWT_Type != DWT_DBL_TYPE) return(DWT_INTERNAL_ERROR);
#endif
/* double check if Length is even */
if(Length & 1) return(DWT_INTERNAL_ERROR);
/* initial mask output */
for(a=InMaskBuf, b = OutMaskBuf, c= OutMaskBuf+(Length>>1); a<InMaskBuf+Length;) {
*b++ = *a++;
*c++ = *a++;
}
/* initial OutBuf to zeros */
memset(OutBuf, (UChar)0, sizeof(DWTDATA)*Length);
i = 0;
a = InMaskBuf;
while(i<Length) {
/* search for a segment */
while(i<Length && (a[i])!=DWT_IN) i++;
start = i;
if(i >= Length) break;
while(i<Length && (a[i])==DWT_IN) i++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -