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

📄 hplx_hor_synthesis_by_lifting.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/* File: "hplx_hor_synthesis_by_lifting.c"                                   */
/* Description: Implementation of the `hplx_synthesis_stage' object for      */
/*              horizontal analysis via lifting.                             */
/* Author: David Taubman                                                     */
/* Affiliation: Hewlett-Packard and                                          */
/*              The University of New South Wales, Australia                 */
/* Acknowledgements: Partly developed in collaboration with                  */
/*                   Christos Chrysafis of HP Labs                           */
/* Version: VM8.6                                                            */
/* Last Revised: 17 October, 2000                                            */
/*****************************************************************************/

/*****************************************************************************/
/* 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.                                                  */
/*****************************************************************************/

/*****************************************************************************/
/* Modifications marked "Christos Chrysafis (HPL)" made to ensure that       */
/* the boundary extension policy for lifting is identical to that used for   */
/* convolution so that convolution vs. lifting is purely an implementation   */
/* decision.  Mods might cause problems for non-symmetric kernels, but that  */
/* should not be relevant to the standard.  The modifications are            */
/* copyrighted by Hewlett-Packard Company with all rights reserved for the   */
/* modified parts.                                                           */
/*****************************************************************************/

/*****************************************************************************/
/* 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 by David Taubman to allow SSO-DWT style extension at tile        */
/* boundaries.  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.                                   */
/*****************************************************************************/

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

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

/*****************************************************************************/
/*                      hplx_hor_synthesis_by_lifting_obj                    */
/*****************************************************************************/

typedef
  struct hplx_hor_synthesis_by_lifting_obj {
    hplx_synthesis_stage_obj base;
    int tile_width, first_idx;
    int kernel_type;
    int num_steps;
    int neg_supports[INFO__MAX_LIFTING_STEPS];
    int pos_supports[INFO__MAX_LIFTING_STEPS];
    float *float_taps[INFO__MAX_LIFTING_STEPS]; /* Only for float-lifting. */
    int *int_taps[INFO__MAX_LIFTING_STEPS]; /* Only for int-lifting. */
    int int_downshifts[INFO__MAX_LIFTING_STEPS]; /* Only for int-lifting. */
    float step_dc_gains[INFO__MAX_LIFTING_STEPS]; /* BBDWT mod by David T */
    float branch_scale[2]; /* Only for float-lifting. */
    int neg_extend, pos_extend;
    float *branch_buf_float[2];
    ifc_int *branch_buf_int[2];
    int num_frames, frame_cols, frame_ref, first_frame_cols;
    float *frame_work_buf_float[2];
    ifc_int *frame_work_buf_int[2];
  } hplx_hor_synthesis_by_lifting_obj, *hplx_hor_synthesis_by_lifting_ref;
  /* The `neg_extend' and `pos_extend' values are the same for all tiles;
     they are the maximum negative and positive support extents, respectively,
     over all steps and are, therefore, safe extension distances for the
     sub-sequences subjected to lifting steps.  Each of the even and odd
     sub-sequence buffers (i.e. the buffers referenced by the entries of
     `branch_buf_float' or `branch_buf_int') has an extra `neg_extend'
     entries which may be indexed below 0 and `pos_extend' entries which
     may be indexed beyond the nominal end of the array (i.e. after
     `branch_cols'[0] or `branch_cols'[1], as appropriate).
         The `num_frames' field holds the number of frames.  The SSO-DWT
     is applied if and only if `num_frames' is not equal to 1.  Even
     though the SSO-DWT is an overlapping transform, the number of frames
     is computed based upon a disjoint partition.  The overlap samples
     are then determined subsequently.  This is important, since it can
     happen that the overlap sample is an entire frame.
         The `frame_cols' field holds the nominal horizontal frame
     dimension; it is meaningful only if `num_frames' > 1.
         The `frame_ref' field holds the horizontal anchor coordinate
     for the frame partition.
         `first_frame_cols' holds the width of the first frame in the current
     tile. */


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

/*****************************************************************************/
/* STATIC                         undo_float_step                            */
/*****************************************************************************/

static void
  undo_float_step(int the_stage,
                  int neg_support, int pos_support, float *taps,
                  float *src, float *dst, int src_cols, int dst_cols,
                  int src_offset, int src_on_left_boundary,
                  int src_on_right_boundary, int skip_first, int skip_last,
                  float stage_dc_gain)

 /* Undoes a single lifting step, removing a contribution due to the
    `src' sequence from the `dst' sequence.  The elements of the `taps'
    array have indices running from -`neg_support' to +`pos_support'.  These
    supports refer to the nominal alignment of the `src' and `dst'
    sub-sequences and are independent of particular boundary locations.
    It can happen that one of the sub-sequences is truncated by a boundary
    while the other is not.  In this case, `src_offset' identifies the
    amount by which the `src' sub-sequence is displaced to the right of
    the `dst' sub-sequence.  It is always a value in the range -1 to 1.  The
    value of `src_offset' should simply be subtracted from `pos_support' and
    added to `neg_support'.  The `src_on_left_boundary' flag indicates
    whether or not the first sample of the `src' buffer lies on the left
    hand boundary of the transform block.  Similarly, `src_on_right_boundary'
    indicates whether or not the last sample of the `src' buffer lies on
    the right hand boundary of the transform block.  This information tells us
    how to perform symmetric extension on the lifting steps.  The
    `skip_first' flag indicates whether or not the lifting step which
    updates the first sample in `dst' should be skipped.  Similarly, the
    `skip_last' flag indicates whether or not the lifting step which updates
    the last sample in `dst' should be skipped.  Skipped lifting steps should
    be replaced by the removal of the `stage_dc_gain' factor from the
    relevant sample in the `dst' array (i.e. division).  Lifting steps must
    sometimes be skipped in this way to perform the SSO-DWT. */

{
  int even_taps, n, p;
  int left_ext, right_ext;
  float sum;
  float *sp, *dp;

  assert(src_cols && dst_cols);
  even_taps = (pos_support+neg_support+1)&1;

  /* Determine extension types.  Note that the extensions for even
     length filters might not replicate the effects of symmetric extension
     in convolution implementations in all cases. */
  if (even_taps)
    { /* Extension for even tap filters. */
      if (src_offset)
        local_error("Cannot start image, tile or frame with an odd indexed "
                    "sample when using even length filters!  Use odd length "
                    "filters!");
      left_ext = symmetric_extension_type(1,(src_cols+dst_cols)&1,
                                          the_stage&1,0);
      right_ext = symmetric_extension_type(1,(src_cols+dst_cols)&1,
                                           the_stage&1,1);
    }
  else
    { /* Extension for odd tap filters. */
      pos_support-=src_offset;
      neg_support+=src_offset;
      taps += src_offset;
      left_ext = (src_on_left_boundary)?0:1;
      right_ext = (src_on_right_boundary)?0:1;
    }

  /* Perform extensions, alternating between left and right extension
     until we are done. */
  sp = src; dp = sp + src_cols - 1;
  pos_support += dst_cols - src_cols;
  for (n=p=1; (n <= neg_support) || (p <= pos_support); )
    {
      int did_something;

      did_something = 0;
      if (n <= neg_support)
        { /* Still need extension on the left. */
          if (left_ext)
            { /* Half-point extension. */
              if (n <= (src_cols+p-1))
                { sp[-n] = sp[n-1]*left_ext; n++; did_something = 1; }
            }
          else
            { /* Nice case for odd length filters; should always work. */
              if (n < (src_cols+p-1))
                { sp[-n] = sp[n]; n++; did_something = 1; }
            }
        }
      if (p <= pos_support)
        { /* Still need extension on the right. */
          if (right_ext)
            { /* Half-point extension. */
              if (p <= (src_cols+n-1))
                { dp[p] = dp[-p+1]*right_ext; p++; did_something = 1; }
            }
          else
            { /* Whole-point extension. */
              if (p < (src_cols+n-1))
                { dp[p] = dp[-p]; p++; did_something = 1; }
            }
        }
      assert(did_something);
    }
  pos_support -= dst_cols - src_cols;

  /* Apply lifting step.  Note that `taps' points to "centre" of support. */

  if (skip_first)
    { *dst /= stage_dc_gain; dst_cols--; dst++; src++; }
  if (skip_last)
    { dst[dst_cols-1] /= stage_dc_gain; dst_cols--; }
  for (; dst_cols > 0; dst_cols--, src++, dst++)
    {
      for (sum=0.0F, n=-neg_support; n <= pos_support; n++)
        sum += src[n] * taps[n];
      *dst -= sum;
    }
}

/*****************************************************************************/
/* STATIC                          undo_int_step                             */
/*****************************************************************************/

static void
  undo_int_step(int the_stage,
                int neg_support, int pos_support, int *taps, int downshift,
                ifc_int *src, ifc_int *dst, int src_cols, int dst_cols,
                int src_offset, int src_on_left_boundary,
                int src_on_right_boundary, int skip_first, int skip_last)

 /* Undoes a single lifting step, removing a contribution due to the
    `src' sequence from the `dst' sequence.  The elements of the `taps'
    array have indices running from -`neg_support' to +`pos_support'.  These
    supports refer to the nominal alignment of the `src' and `dst'
    sub-sequences and are independent of particular boundary locations.
    It can happen that one of the sub-sequences is truncated by a boundary
    while the other is not.  In this case, `src_offset' identifies the
    amount by which the `src' sub-sequence is displaced to the right of
    the `dst' sub-sequence.  It is always a value in the range -1 to 1.  The
    value of `src_offset' should simply be subtracted from `pos_support' and
    added to `neg_support'.  The `src_on_left_boundary' flag indicates
    whether or not the first sample of the `src' buffer lies on the left
    hand boundary of the transform block.  Similarly, `src_on_right_boundary'
    indicates whether or not the last sample of the `src' buffer lies on
    the right hand boundary of the transform block.  This information tells us
    how to perform symmetric extension on the lifting steps.  The
    `skip_first' flag indicates whether or not the lifting step which
    updates the first sample in `dst' should be skipped.  Similarly, the
    `skip_last' flag indicates whether or not the lifting step which updates
    the last sample in `dst' should be skipped.  Lifting steps must sometimes
    be skipped to perform the SSO-DWT. */


{
  int even_taps, n, p;
  int left_ext, right_ext;
  std_int sum, offset;
  ifc_int *sp,*dp;

  assert(src_cols && dst_cols);
  even_taps = (pos_support+neg_support+1)&1;

  /* Determine extension types.  Note that the extensions for even
     length filters might not replicate the effects of symmetric extension
     in convolution implementations in all cases. */
  if (even_taps)
    { /* Extension for even tap filters. */
      if (src_offset)
        local_error("Cannot start image, tile or frame with an odd indexed "
                    "sample when using even length filters!  Use odd length "
                    "filters!");
      left_ext = symmetric_extension_type(1,(src_cols+dst_cols)&1,
                                          the_stage&1,0);

⌨️ 快捷键说明

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