⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hplx_vert_synthesis_by_convolution.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/* File: "hplx_vert_synthesis_by_convolution.c"                              */
/* Description: Implementation of the `hplx_synthesis_stage' object for      */
/*              vertical synthesis via convolution.                          */
/* Author: David Taubman                                                     */
/* Affiliation: Hewlett-Packard and                                          */
/*              The University of New South Wales, Australia                 */
/* Acknowledgements: Partly developed in collaboration with                  */
/*                   Christos Chrysafix of HP Labs                           */
/* Version: VM9.0                                                            */
/* Last Revised: 20 April, 2001                                              */
/*****************************************************************************/

/*****************************************************************************/
/* Modifications tagged with comment lines or delimiters involving the       */
/* string, "David T mod" or "mod by David T", have been made by David        */
/* Taubman; they are copyrighted by Hewlett-Packard Company with all rights  */
/* reserved for the modified parts.                                          */
/*****************************************************************************/

/*****************************************************************************/
/* Modifications tagged with comment lines or delimiters involving the       */
/* string "BBDWT mod" have been made to implement the single-sample          */
/* overlap Wavelet transform within the frames paradigm -- this is the       */
/* BBDWT transform proposed by Canon Research France and accepted at the     */
/* meeting in Seoul, Korea.                                                  */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to support arbitrary reference points for the   */
/* transform and the various regular partitions, so as to facilitate         */
/* cropping and geometric transformations in the compressed domain and to    */
/* enable full support for CRF's single-sample overlap Wavelet transform,    */
/* as originally documented in Seoul.  Changes are too numerous to flag      */
/* individually within the code.  Changes copyrighted by HP with all rights  */
/* reserved for the modified parts.                                          */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to support interface modifications, arbitrary   */
/* changes in coding parameters from component to component and from tile    */
/* to tile, to support the full generality of PART-1 of the JPEG2000         */
/* standard, and to support most anticipated generality of PART-2.  Changes  */
/* are too numerous to flag individually within the code, which in some      */
/* places has been completely rewritten.  All changes copyrighted by HP with */
/* all rights reserved for the modified parts.                               */
/*****************************************************************************/

/*****************************************************************************/
/* Modified for general wavelet decompositions.                              */
/* Copyright 2000 Science Applications International Corporation (SAIC).     */
/* Copyright 1995 University of Arizona, Arizona Board of Regents.           */
/* All Rights Reserved for modified parts.                                   */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by Brendt Wohlberg (Los Alamos National Laboratory) to support   */
/* use of even length filters on tiles of arbitrary dimension and offset     */
/* (as per proposal WG1N1842 submitted at WG1 Rochester meeting). All        */
/* modifications are Copyright 2000 University of California.                */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by Jianxin Wei, Australian Defence Force Academy (ADFA)          */
/* to implement the Odd Tile-Size Low-Pass First Convention (OTLPF_CONVENTION)*/
/* Copyright 2000 University of New South Wales, Australia.                  */
/* All rights reserved for modified parts.                                   */
/*****************************************************************************/

#include <local_services.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <ifc.h>
#include "hplx_vert_convolution.h"
#include "hplx_synthesis_local.h"

/* ========================================================================= */
/* ---------------------- Definition of Extended Object -------------------- */
/* ========================================================================= */

/*****************************************************************************/
/*                            hplx_polyphase_kernel                          */
/*****************************************************************************/

typedef
  struct hplx_polyphase_kernel {
    int neg_support, pos_support;
    float *taps;
  } hplx_polyphase_kernel, *hplx_polyphase_kernel_ptr;
  /* This structure represents a single polyphase operator, of which four
     are required to completely synthesize a 1-D signal from its low- and
     high-pass subbands.  The kernel represents the contribution of one
     of the input subbands to either the even or odd sub-sequence of the
     output.  The kernel taps appear in inner product fashion and have the
     designated region of support.  Note that the `taps' array is dynamically
     allocated and must be destroyed upon termination of the containing
     object. */

/*****************************************************************************/
/*                  hplx_vert_synthesis_by_convolution_obj                   */
/*****************************************************************************/

typedef
  struct hplx_vert_synthesis_by_convolution_obj {
    hplx_synthesis_stage_obj base;
    int cols;
    int next_row_idx;
    hplx_polyphase_kernel branch_to_even[2];
    hplx_polyphase_kernel branch_to_odd[2];
    int even_taps;
    hplx_rolling_buffer branch_windows[2];
    float *conversion_buf;
    float *taps_copy;
    int *sign_flips_buffer;
    float *ps_prev_buf;
    float *ps_low_buf;
    float *ps_high_buf;
    int first_row_idx;
    /* LANL Even Length Begin */
    /* Flag indicating whether the final lowpass row has been generated
       by the preprocessor */
    int extra_right_low_ready;
    /* Index of the current position in the lookahead buffer for highpass
       rows */
    int next_high_lookahead;
    /* Number of rows in the highpass lookahead buffer */
    int high_lookahead_rows;
    /* LANL Even Length End */
  } hplx_vert_synthesis_by_convolution_obj,
    *hplx_vert_synthesis_by_convolution_ref;
  /* Extends the basic `hplx_synthesis_stage' object for the purpose of
     vertical synthesis by convolution.
         The `cols' field identifies the width of rows processed by this
     synthesis stage.
         The `next_row_idx' field holds the zero-based index of the next
     row to be synthesized.
         The `branch_to_even' array holds two polyphase kernels,
     corresponding to the operators which map the two input branches
     (low- and high-pass subbands) into the even indexed output rows,
     i.e. rows 0,2,4, etc.
         The `branch_to_odd' array holds two polyphase kernels,
     corresponding to the operators which map the two input branches
     (low- and high-pass subbands) into the odd indexed output rows,
     i.e. 1,3,5, etc.
         `even_taps' indicates whether the filter kernels have even or
     odd length.  This affects the type of symmetric extension which
     must be applied.
         The `branch_windows' array manages a rolling window of input
     rows for each of the two input subbands.
         The `conversion_buf' field points to a buffer which is large
     enough to hold an entire reconstructed row of the image.  It is
     only required by calls to `pull_line_fixed'.
         The `taps_copy' and `sign_flips_buffer' arrays must both be
     sufficiently large to cover the support of any of the high-pass
     polyphase kernels (i.e. those in `branch_to_even[1]' and
     `branch_to_odd[1]').  They are used only with even-length filters
     in order to mimic the sign reversal which is required for symmetric
     extension of the high-pass subbands.
         `next_frame_idx' is a counter which identifies the index of the next
     frame to be processed.  It is reset to 0 at the start of each tile.
         The `first_row_idx' field holds the absolute index of the
     first row, with respect to the absolute canvas coordinate system. */


/* ========================================================================= */
/* ---------------------------- Internal Functions ------------------------- */
/* ========================================================================= */

/* LANL Even Length Begin */
/*****************************************************************************/
/* STATIC                      synthesis_end_filter                          */
/*****************************************************************************/

/* Implementation of (L',H') -> (L,L) preprocessing */
static void synthesis_end_filter(float* spL, float* spH,
                                 float* dp0, float* dp1, int ncols) {
  int n;
  float d0, d1;

  for (n = 0; n < ncols; n++) {
    d0 = (spL[n] + spH[n]/2.0F);
    d1 = (spL[n] - spH[n]/2.0F);

    dp0[n] = d0;
    dp1[n] = d1;
    spH[n] = 0.0;
 
  }
}
/* LANL Even Length End */

/*****************************************************************************/
/* STATIC                    create_polyphase_kernel                         */
/*****************************************************************************/

static void
  create_polyphase_kernel(hplx_polyphase_kernel_ptr kernel,
                          int input_odd, int output_odd,
                          int neg_support, int pos_support, float *taps)

 /* This function fills out the contents of the polyphase kernel structure
    referenced by `kernel', by reversing and sub-sampling the impulse
    response supplied via `taps', which may be indexed as `taps'[k] where
    k ranges from -`neg_support' to +`pos_support'.  The `input_odd'
    argument identifies whether this impulse response is notionally
    centred on even (low-pass) or odd (high-pass) samples, while the
    `output_odd' argument identifies whether the polyphase kernel is to
    generate the even or odd sub-sequence of the reconstructed signal. */

{
  int displacement, n;

  if (output_odd)
    output_odd = 1; /* Make sure. */
  if (input_odd)
    input_odd = 1; /* Make sure. */
  displacement = output_odd - input_odd;
  kernel->pos_support = (displacement + neg_support)>>1;
  kernel->neg_support = (pos_support - displacement)>>1;
  if ((kernel->neg_support < 0) || (kernel->pos_support < 0))
    return;
  kernel->taps = (float *)
    local_malloc(XFORM_MEM_KEY,
                 sizeof(float)*(kernel->neg_support+kernel->pos_support+1));
  kernel->taps += kernel->neg_support;
  for (n=-kernel->neg_support; n <= kernel->pos_support; n++)
    kernel->taps[n] = taps[displacement - 2*n];
}

/*****************************************************************************/
/* STATIC                    complete_pull_line                              */
/*****************************************************************************/

static void
  complete_pull_line(hplx_synthesis_stage_ref base, float *line_buf)

 /* This function does almost all the work of `__pull_line_float'. */

{
  hplx_vert_synthesis_by_convolution_ref self =
    (hplx_vert_synthesis_by_convolution_ref) base;
  hplx_polyphase_kernel_ptr kernel;
  hplx_rolling_buffer_ptr window=NULL;  /* TJF: =NULL to avoid warnings */
  float *taps, **source[2], *dp, sum;
  int min_row_idx, neg, pos, support;
  int b, n, k;
  int *sign_flips[2];

  /* LANL Even Length Begin */
  /* Set flags to distinguish between cases based on input length
     and offset respectively */
  int oddevencase = 0;
  int oddoddcase = 0;
  int evenevencase = 0;

  if (self->even_taps) {
    if ((self->branch_windows[0].rows+self->branch_windows[1].rows)%2) {
      if (self->first_row_idx%2)
        oddoddcase = 1;
      else
        oddevencase = 1;
    } else {
      if (!(self->first_row_idx%2))
        evenevencase = 1;
    }
  }
  /* LANL Even Length End */

  if ((self->branch_windows[0].rows+self->branch_windows[1].rows) == 1)
    { /* Signals of length (height) < 2 must be treated specially. */

      /* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
      int first_row_odd;
      if(!base->otlpf_convention)
        first_row_odd = self->first_row_idx & 1;
      else
        first_row_odd =0;
      /** always treat it as if it were even. **/
      /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */

      base->branches[first_row_odd]->pull_line_float(
        base->branches[first_row_odd],line_buf,self->cols);
      return;
    }

    /* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
  if(!base->otlpf_convention)
  {
        /* LANL Even Length Begin */
        /* For even length filters, switch kernel order so that filter centers
           are at (1/2, 1/2) for even input offset and (-1/2, -1/2) for odd input
           offset. */
        if (self->even_taps) {
                if (self->first_row_idx%2) {
                if (self->next_row_idx & 1)
                        kernel = self->branch_to_even;
                else
                        kernel = self->branch_to_odd;
                } else {
                if (self->next_row_idx & 1)
                        kernel = self->branch_to_even;
                else
                        kernel = self->branch_to_odd;
                }
        }       else {
        if (self->next_row_idx & 1)
                kernel = self->branch_to_odd;
        else
                kernel = self->branch_to_even;
        }
  /* LANL Even Length End */
  }
  else
  {
        if ((self->next_row_idx-self->first_row_idx) & 1)
    kernel = self->branch_to_odd;
  else
    kernel = self->branch_to_even;
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -