jpc_qmfb.c
来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· C语言 代码 · 共 1,657 行 · 第 1/3 页
C
1,657 行
/*
* Copyright (c) 1999-2000 Image Power, Inc. and the University of
* British Columbia.
* Copyright (c) 2001-2003 Michael David Adams.
* Copyright (c) 2005-2006 artofcode LLC.
*
* All rights reserved.
*/
/* __START_OF_JASPER_LICENSE__
*
* JasPer License Version 2.0
*
* Copyright (c) 1999-2000 Image Power, Inc.
* Copyright (c) 1999-2000 The University of British Columbia
* Copyright (c) 2001-2003 Michael David Adams
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person (the
* "User") obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* 1. The above copyright notices and this permission notice (which
* includes the disclaimer below) shall be included in all copies or
* substantial portions of the Software.
*
* 2. The name of a copyright holder shall not be used to endorse or
* promote products derived from the Software without specific prior
* written permission.
*
* THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
* LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
* THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
* "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
* INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
* PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
* THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
* EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
* BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
* PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
* GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
* ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
* IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
* SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
* AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
* SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
* THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
* PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
* RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
* EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
*
* __END_OF_JASPER_LICENSE__
*/
/*
* Quadrature Mirror-Image Filter Bank (QMFB) Library
*
* $Id$
*/
/******************************************************************************\
* Includes.
\******************************************************************************/
#include <assert.h>
#include "jasper/jas_fix.h"
#include "jasper/jas_malloc.h"
#include "jasper/jas_math.h"
#include "jasper/jas_debug.h"
#include "jpc_qmfb.h"
#include "jpc_tsfb.h"
#include "jpc_math.h"
#ifndef USE_ASM_WIN32
# if defined(_WIN32) && !defined(_WIN64)
# define USE_ASM_WIN32
# endif
#endif
/******************************************************************************\
*
\******************************************************************************/
static jpc_qmfb1d_t *jpc_qmfb1d_create(void);
static int jpc_ft_getnumchans(jpc_qmfb1d_t *qmfb);
static int jpc_ft_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters);
static int jpc_ft_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters);
static void jpc_ft_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
static void jpc_ft_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
static int jpc_ns_getnumchans(jpc_qmfb1d_t *qmfb);
static int jpc_ns_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters);
static int jpc_ns_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters);
static void jpc_ns_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
static void jpc_ns_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
#ifdef USE_ASM_WIN32
static void jpc_win32_ns_synthesize( jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
#endif
/******************************************************************************\
*
\******************************************************************************/
jpc_qmfb1dops_t jpc_ft_ops = {
jpc_ft_getnumchans,
jpc_ft_getanalfilters,
jpc_ft_getsynfilters,
jpc_ft_analyze,
jpc_ft_synthesize
};
jpc_qmfb1dops_t jpc_ns_ops = {
jpc_ns_getnumchans,
jpc_ns_getanalfilters,
jpc_ns_getsynfilters,
jpc_ns_analyze,
#ifdef USE_ASM_WIN32
jpc_win32_ns_synthesize
#else
jpc_ns_synthesize
#endif
};
/******************************************************************************\
*
\******************************************************************************/
static void jpc_qmfb1d_setup(jpc_fix_t *startptr, int startind, int endind,
int intrastep, jpc_fix_t **lstartptr, int *lstartind, int *lendind,
jpc_fix_t **hstartptr, int *hstartind, int *hendind)
{
*lstartind = JPC_CEILDIVPOW2(startind, 1);
*lendind = JPC_CEILDIVPOW2(endind, 1);
*hstartind = JPC_FLOORDIVPOW2(startind, 1);
*hendind = JPC_FLOORDIVPOW2(endind, 1);
*lstartptr = startptr;
*hstartptr = &startptr[(*lendind - *lstartind) * intrastep];
}
static void jpc_qmfb1d_split(jpc_fix_t *startptr, int startind, int endind,
register int step, jpc_fix_t *lstartptr, int lstartind, int lendind,
jpc_fix_t *hstartptr, int hstartind, int hendind)
{
int bufsize = JPC_CEILDIVPOW2(endind - startind, 2);
#if !defined(HAVE_VLA)
#define QMFB_SPLITBUFSIZE 4096
jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE];
#else
jpc_fix_t splitbuf[bufsize];
#endif
jpc_fix_t *buf = splitbuf;
int llen;
int hlen;
int twostep;
jpc_fix_t *tmpptr;
register jpc_fix_t *ptr;
register jpc_fix_t *hptr;
register jpc_fix_t *lptr;
register int n;
int state;
twostep = step << 1;
llen = lendind - lstartind;
hlen = hendind - hstartind;
#if !defined(HAVE_VLA)
/* Get a buffer. */
if (bufsize > QMFB_SPLITBUFSIZE) {
if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
/* We have no choice but to commit suicide in this case. */
jas_error( JAS_ERR_MALLOC_FAILURE_JPC_QMFB1D_SPLIT,
"JAS_ERR_MALLOC_FAILURE_JPC_QMFB1D_SPLIT"
);
return;
}
}
#endif
if (hstartind < lstartind) {
/* The first sample in the input signal is to appear
in the highpass subband signal. */
/* Copy the appropriate samples into the lowpass subband
signal, saving any samples destined for the highpass subband
signal as they are overwritten. */
tmpptr = buf;
ptr = &startptr[step];
lptr = lstartptr;
n = llen;
state = 1;
while (n-- > 0) {
if (state) {
*tmpptr = *lptr;
++tmpptr;
}
*lptr = *ptr;
ptr += twostep;
lptr += step;
state ^= 1;
}
/* Copy the appropriate samples into the highpass subband
signal. */
/* Handle the nonoverwritten samples. */
hptr = &hstartptr[(hlen - 1) * step];
ptr = &startptr[(((llen + hlen - 1) >> 1) << 1) * step];
n = hlen - (tmpptr - buf);
while (n-- > 0) {
*hptr = *ptr;
hptr -= step;
ptr -= twostep;
}
/* Handle the overwritten samples. */
n = tmpptr - buf;
while (n-- > 0) {
--tmpptr;
*hptr = *tmpptr;
hptr -= step;
}
} else {
/* The first sample in the input signal is to appear
in the lowpass subband signal. */
/* Copy the appropriate samples into the lowpass subband
signal, saving any samples for the highpass subband
signal as they are overwritten. */
state = 0;
ptr = startptr;
lptr = lstartptr;
tmpptr = buf;
n = llen;
while (n-- > 0) {
if (state) {
*tmpptr = *lptr;
++tmpptr;
}
*lptr = *ptr;
ptr += twostep;
lptr += step;
state ^= 1;
}
/* Copy the appropriate samples into the highpass subband
signal. */
/* Handle the nonoverwritten samples. */
ptr = &startptr[((((llen + hlen) >> 1) << 1) - 1) * step];
hptr = &hstartptr[(hlen - 1) * step];
n = hlen - (tmpptr - buf);
while (n-- > 0) {
*hptr = *ptr;
ptr -= twostep;
hptr -= step;
}
/* Handle the overwritten samples. */
n = tmpptr - buf;
while (n-- > 0) {
--tmpptr;
*hptr = *tmpptr;
hptr -= step;
}
}
#if !defined(HAVE_VLA)
/* If the split buffer was allocated on the heap, free this memory. */
if (buf != splitbuf) {
jas_free(buf);
}
#endif
}
static void jpc_qmfb1d_join(jpc_fix_t *startptr, int startind, int endind,
register int step, jpc_fix_t *lstartptr, int lstartind, int lendind,
jpc_fix_t *hstartptr, int hstartind, int hendind)
{
int bufsize = JPC_CEILDIVPOW2(endind - startind, 2);
#if !defined(HAVE_VLA)
#define QMFB_JOINBUFSIZE 4096
jpc_fix_t joinbuf[QMFB_JOINBUFSIZE];
#else
jpc_fix_t joinbuf[bufsize];
#endif
jpc_fix_t *buf = joinbuf;
int llen;
int hlen;
int twostep;
jpc_fix_t *tmpptr;
register jpc_fix_t *ptr;
register jpc_fix_t *hptr;
register jpc_fix_t *lptr;
register int n;
int state;
#if !defined(HAVE_VLA)
/* Allocate memory for the join buffer from the heap. */
if (bufsize > QMFB_JOINBUFSIZE) {
if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
/* We have no choice but to commit suicide. */
jas_error( JAS_ERR_MALLOC_FAILURE_JPC_QMFB1D_JOIN,
"JAS_ERR_MALLOC_FAILURE_JPC_QMFB1D_JOIN"
);
return;
}
}
#endif
twostep = step << 1;
llen = lendind - lstartind;
hlen = hendind - hstartind;
if (hstartind < lstartind) {
/* The first sample in the highpass subband signal is to
appear first in the output signal. */
/* Copy the appropriate samples into the first phase of the
output signal. */
tmpptr = buf;
hptr = hstartptr;
ptr = startptr;
n = (llen + 1) >> 1;
while (n-- > 0) {
*tmpptr = *ptr;
*ptr = *hptr;
++tmpptr;
ptr += twostep;
hptr += step;
}
n = hlen - ((llen + 1) >> 1);
while (n-- > 0) {
*ptr = *hptr;
ptr += twostep;
hptr += step;
}
/* Copy the appropriate samples into the second phase of
the output signal. */
ptr -= (lendind > hendind) ? (step) : (step + twostep);
state = !((llen - 1) & 1);
lptr = &lstartptr[(llen - 1) * step];
n = llen;
while (n-- > 0) {
if (state) {
--tmpptr;
*ptr = *tmpptr;
} else {
*ptr = *lptr;
}
lptr -= step;
ptr -= twostep;
state ^= 1;
}
} else {
/* The first sample in the lowpass subband signal is to
appear first in the output signal. */
/* Copy the appropriate samples into the first phase of the
output signal (corresponding to even indexed samples). */
lptr = &lstartptr[(llen - 1) * step];
ptr = &startptr[((llen - 1) << 1) * step];
n = llen >> 1;
tmpptr = buf;
while (n-- > 0) {
*tmpptr = *ptr;
*ptr = *lptr;
++tmpptr;
ptr -= twostep;
lptr -= step;
}
n = llen - (llen >> 1);
while (n-- > 0) {
*ptr = *lptr;
ptr -= twostep;
lptr -= step;
}
/* Copy the appropriate samples into the second phase of
the output signal (corresponding to odd indexed
samples). */
ptr = &startptr[step];
hptr = hstartptr;
state = !(llen & 1);
n = hlen;
while (n-- > 0) {
if (state) {
--tmpptr;
*ptr = *tmpptr;
} else {
*ptr = *hptr;
}
hptr += step;
ptr += twostep;
state ^= 1;
}
}
#if !defined(HAVE_VLA)
/* If the join buffer was allocated on the heap, free this memory. */
if (buf != joinbuf) {
jas_free(buf);
}
#endif
}
/******************************************************************************\
* Code for 5/3 transform.
\******************************************************************************/
static int jpc_ft_getnumchans(jpc_qmfb1d_t *qmfb)
{
/* Avoid compiler warnings about unused parameters. */
qmfb = 0;
return 2;
}
static int jpc_ft_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
{
/* Avoid compiler warnings about unused parameters. */
qmfb = 0;
len = 0;
filters = 0;
jas_error( JAS_ERR_INCOMPLETE_STUB_INVOKED_JPC_FT_GETANALFILTERS,
"JAS_ERR_INCOMPLETE_STUB_INVOKED_JPC_FT_GETANALFILTERS"
);
return -1;
}
static int jpc_ft_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
{
jas_seq_t *lf;
jas_seq_t *hf;
/* Avoid compiler warnings about unused parameters. */
qmfb = 0;
lf = 0;
hf = 0;
if (len > 1 || (!len)) {
if (!(lf = jas_seq_create(-1, 2))) {
goto error;
}
jas_seq_set(lf, -1, jpc_dbltofix(0.5));
jas_seq_set(lf, 0, jpc_dbltofix(1.0));
jas_seq_set(lf, 1, jpc_dbltofix(0.5));
if (!(hf = jas_seq_create(-1, 4))) {
goto error;
}
jas_seq_set(hf, -1, jpc_dbltofix(-0.125));
jas_seq_set(hf, 0, jpc_dbltofix(-0.25));
jas_seq_set(hf, 1, jpc_dbltofix(0.75));
jas_seq_set(hf, 2, jpc_dbltofix(-0.25));
jas_seq_set(hf, 3, jpc_dbltofix(-0.125));
} else if (len == 1) {
if (!(lf = jas_seq_create(0, 1))) {
goto error;
}
jas_seq_set(lf, 0, jpc_dbltofix(1.0));
if (!(hf = jas_seq_create(0, 1))) {
goto error;
}
jas_seq_set(hf, 0, jpc_dbltofix(2.0));
} else {
jas_error( JAS_ERR_INVALID_LEN_PARAM_JPC_FT_GETSYNFILTERS,
"JAS_ERR_INVALID_LEN_PARAM_JPC_FT_GETSYNFILTERS"
);
goto error;
}
filters[0] = lf;
filters[1] = hf;
return 0;
error:
if (lf) {
jas_seq_destroy(lf);
}
if (hf) {
jas_seq_destroy(hf);
}
return -1;
}
#define NFT_LIFT0(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pluseq) \
{ \
register jpc_fix_t *lptr = (lstartptr); \
register jpc_fix_t *hptr = (hstartptr); \
register int n = (hendind) - (hstartind); \
if ((hstartind) < (lstartind)) { \
pluseq(*hptr, *lptr); \
hptr += (step); \
--n; \
} \
if ((hendind) >= (lendind)) { \
--n; \
} \
while (n-- > 0) { \
pluseq(*hptr, jpc_fix_asr(jpc_fix_add(*lptr, lptr[(step)]), 1)); \
hptr += (step); \
lptr += (step); \
} \
if ((hendind) >= (lendind)) { \
pluseq(*hptr, *lptr); \
} \
}
#define NFT_LIFT1(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pluseq) \
{ \
register jpc_fix_t *lptr = (lstartptr); \
register jpc_fix_t *hptr = (hstartptr); \
register int n = (lendind) - (lstartind); \
if ((hstartind) >= (lstartind)) { \
pluseq(*lptr, *hptr); \
lptr += (step); \
--n; \
} \
if ((lendind) > (hendind)) { \
--n; \
} \
while (n-- > 0) { \
pluseq(*lptr, jpc_fix_asr(jpc_fix_add(*hptr, hptr[(step)]), 2)); \
lptr += (step); \
hptr += (step); \
} \
if ((lendind) > (hendind)) { \
pluseq(*lptr, *hptr); \
} \
}
#define RFT_LIFT0(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pmeqop) \
{ \
register jpc_fix_t *lptr = (lstartptr); \
register jpc_fix_t *hptr = (hstartptr); \
register int n = (hendind) - (hstartind); \
if ((hstartind) < (lstartind)) { \
*hptr pmeqop *lptr; \
hptr += (step); \
--n; \
} \
if ((hendind) >= (lendind)) { \
--n; \
} \
while (n-- > 0) { \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?