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

📄 hpbit_stream_in.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/* File: "hpbit_stream_in.c"                                                 */
/* Description: Reference implementation of the `stream_in' object.          */
/* Author: David Taubman                                                     */
/* Affiliation: Hewlett-Packard and                                          */
/*              The University of New South Wales, Australia                 */
/* Acknowledgements: Partly developed in collaboration with Salma Soudagar   */
/*                   of Motorola, Switzerland, and her colleagues            */
/* Version: VM9.0                                                            */
/* Last Revised: 19 April, 2001                                              */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to avoid the need for byte stuffing when resync */
/* markers are in use.  This simplifies the code and substantially improves  */
/* the usefulness of the system for applications requiring error resilience. */
/* Copyright 1999 by Hewlett-Packard Company 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 Gene Wu & Michael Gormish to add real markers for COD/COC and */
/* QCD/QCC.                                                                  */
/* All changes copyright 2000 by Ricoh Silicon Valley  with all rights       */
/* reserved for the modified parts.                                          */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to implement changes in Tokyo between CD and    */
/* FCD for Part-1 of the standard.  Copyrighted by HP with all rights        */
/* reserved for the modified parts.                                          */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to incorporate changes to the POC marker (used  */
/* to be POD).  Changes are quite extensive and not always explicitly        */
/* When flagged, the relevant comment string is "DST POC mod".               */
/* Copyright 2000 The University of New South Wales.                         */
/* All rights reserved for the modified parts.                               */
/*****************************************************************************/

#include <local_services.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <ifc.h>
#include <markers.h>
#include "hpbit_stream_in_local.h"
#include "hpbit_markers.h"


/* ========================================================================= */
/* ------------------------------ Macros ----------------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/*               `fetch_data_byte' and `fetch_non_data_byte'                 */
/*****************************************************************************/
  /* Note: file accesses are categorized as data bytes or non-data bytes.
     Data accesses occur within the body of a tile-part, i.e. from immediately
     after the SOD marker, up until the next SOT or EOC marker, or the end
     of the file.  Non-data accesses occur everywhere else.  In the absence
     of errors, non-data accesses correspond exclusively to marker codes.  In
     the presence of errors, however, we may need to make non-data accesses
     to skip over bytes which occur between the nominal end of the most
     recent tile-part (as indicated by its length field) and the next marker
     code (should be SOT or EOC). */

#define fetch_data_byte(_self,_tp)                                     \
  (((_tp->data_bytes_left--) <= 0)?                                    \
   (EOF):((_tp->data != NULL)?((int)(*(_tp->data++))):(getc(_self->fp))))

#define fetch_non_data_byte(_self)                                     \
  (((((_self->non_data_bytes_left--) <= 0)) && _self->byte_limit_set)? \
   (EOF):(getc(_self->fp)))


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

/*****************************************************************************/
/* STATIC                      return_data_byte                              */
/*****************************************************************************/

static void
  return_data_byte(hpbit_stream_in_ref self, hpbit_tilepart_ptr tp, int val)

 /* Can use this function to return one byte previously fetched using
    `fetch_data_byte'.  No more than one byte may generally be returned. */

{
  assert(tp->data_bytes_left < tp->data_bytes);
  tp->data_bytes_left++;
  if (tp->data != NULL)
    {
      assert(tp->data > tp->data_handle);
      tp->data--;
    }
  else
    {
      ungetc(val,self->fp);
    }
}

/*****************************************************************************/
/* STATIC                   read_non_data_bytes                              */
/*****************************************************************************/

static int
  read_non_data_bytes(hpbit_stream_in_ref self, void *buf, int num_bytes)

 /* Reads at most `num_bytes' bytes into the supplied buffer and returns
    the number of bytes actually read.  This may be smaller than `num_bytes'
    if the end of file is encountered, or if `self->byte_limit_set' is
    true (non-zero) and the limit identified by `self->non_data_bytes_left'
    is reached. */

{
  if (self->byte_limit_set && (num_bytes > self->non_data_bytes_left))
    num_bytes = self->non_data_bytes_left;
  if (num_bytes <= 0)
    return(0);
  num_bytes = fread(buf,1,num_bytes,self->fp);
  self->non_data_bytes_left -= num_bytes;
  return(num_bytes);
}

/*****************************************************************************/
/* STATIC              buffer_remaining_tilepart_bytes                       */
/*****************************************************************************/

static void
  buffer_remaining_tilepart_bytes(hpbit_stream_in_ref self,
                                  hpbit_tilepart_ptr tp)

 /* This function reads and buffers any outstanding bytes for the supplied
    tile-part (referenced by `tp').  An error is generated if the tile-part
    has the `actual_length_unknown' flag set since this suggests that there
    should be no more tile-parts in the codestream and hence there should
    be no reason to buffer the current tile-part.
        The function reads the input file byte by byte until an SOT or EOC
    marker is encountered, adjusting the `data_bytes', `data_bytes_left' and
    `self->non_data_bytes_left' fields in the event that this delimiting
    marker occurs prematurely. */

{
  int num_bytes, byte_val, have_ff;
  std_byte *buf, *buf_handle;

  assert(!self->have_sot);
  assert(tp->data == NULL);
  if (tp->actual_length_unknown)
    local_error("Only the last tile-part in the codestream is allowed to "
                "have a zero-valued tile-part length field!");
  if (tp->data_bytes_left <= 0)
    return;
  buf = (std_byte *)
    local_malloc(HPBIT_MEM_KEY,tp->data_bytes_left);
  buf_handle = buf;
  have_ff = 0;
  num_bytes = 0;
  while ((byte_val = fetch_data_byte(self,tp)) != EOF)
    {
      *(buf++)= (std_byte) byte_val;
      num_bytes++;
      if (have_ff)
        {
          if (byte_val == (MARKER_SOT & 0x00FF))
            {
              self->have_sot = 1;
              num_bytes -= 2;
              tp->data_bytes_left += 2;
              self->non_data_bytes_left -= 2;
              break;
            }
          else if (byte_val == (MARKER_EOC & 0x00FF))
            {
              num_bytes -= 2;
              tp->data_bytes_left += 2;
              self->non_data_bytes_left -= 2;
              break;
            }
        }
      have_ff = (byte_val == 0x00FF);
    }
  if (tp->data_bytes_left >= 0)
    { /* Encountered a premature marker. */
      tp->data_bytes -= tp->data_bytes_left;
      self->non_data_bytes_left += tp->data_bytes_left;
    }
  tp->data_bytes_left = num_bytes;
  tp->data = tp->data_handle = buf_handle;
}

/*****************************************************************************/
/* STATIC                     copy_from_big_endian                           */
/*****************************************************************************/

static void
  copy_from_big_endian(void *src, void *dst, int num_words, int precision)

 /* Copies the `src' data to the `dst' data and performs and byte reversal
    required to convert Big Endian quantities in `src' to quantities with
    the current machine's byte order in `src'. */

{
  int bigendian, n;
  std_byte *sp, *dp;

  bigendian = 1;
  sp = (std_byte *)(&bigendian);
  *sp = 0;
  if (bigendian || (precision == 1))
    {
      memcpy(dst,src,num_words*precision);
      return;
    }
  assert(num_words != 0);
  if (precision == 2)
    {
      for (sp=(std_byte *) src, dp=(std_byte *) dst,
           n=num_words; n > 0; n--, sp+=2, dp+=2)
        {
          dp[0] = sp[1];
          dp[1] = sp[0];
        }
    }
  else if (precision == 4)
    {
      for (sp=(std_byte *) src, dp=(std_byte *) dst,
           n=num_words; n > 0; n--, sp+=4, dp+=4)
        {
          dp[0] = sp[3];
          dp[1] = sp[2];
          dp[2] = sp[1];
          dp[3] = sp[0];
        }
    }
  else
    assert(0);
}

/*****************************************************************************/
/* STATIC                      destroy_pre_marker                            */
/*****************************************************************************/

static void
  destroy_pre_marker(hpbit_pre_marker_ptr pm)
{
  hpbit_marker_elt_ptr elt;

  while ((elt = pm->elements) != NULL)
    {
      pm->elements = elt->next;
      if (elt->buf != NULL)
        local_free(elt->buf);
      local_free(elt);
    }
  local_free(pm);
}

/*****************************************************************************/
/* STATIC                        destroy_markers                             */
/*****************************************************************************/

static void
  destroy_markers(hpbit_markers_ptr markers, hpbit_tilepart_ptr tp)
{
  hpbit_codestream_marker_ptr cp;
  hpbit_pre_marker_ptr pm;

  while ((cp = markers->codestream_markers) != NULL)
    {
      markers->codestream_markers = cp->next;
      if (cp->accesses == 0)
        {
          int code;

          code = cp->buf[0]; code <<= 8; code += cp->buf[1];
          if (tp == NULL)
            local_printf(0,76,"Warning: Marker code %0x in global header "
                         "was not accessed!",code);
          else
            local_printf(0,76,"Warning: Marker code %0x in tile %d "
                         "was not accessed!",code,tp->tnum);
        }
	  if(cp->buf != NULL)
		local_free(cp->buf);
      local_free(cp);
    }
  while ((pm = markers->pre_markers) != NULL)
    {
      markers->pre_markers = pm->next;
      destroy_pre_marker(pm);
    }
  if (markers->params.components != NULL)
    local_free(markers->params.components);
  markers->params.components = NULL;
}

/*****************************************************************************/
/* STATIC                       destroy_tilepart                             */
/*****************************************************************************/

static void
  destroy_tilepart(hpbit_tilepart_ptr tp)
{
  destroy_markers(&(tp->markers),tp);
  if  (tp->data_handle != NULL)
    local_free(tp->data_handle);
  local_free(tp);
}

/*****************************************************************************/
/* STATIC                      read_markers                                  */
/*****************************************************************************/

static std_ushort
  read_markers(hpbit_stream_in_ref self, hpbit_tilepart_ptr tp)

 /* Reads markers until an appropriate delimiter is encountered, returning
    the delimiting marker.  The function adds the markers onto the
    `codestream_markers' list in the `global_markers' structure within
    `self' or the `markers' structure within `tile', depending upon whether
    or not `tile' is NULL.  Recognized marker section delimiters are
    SOT, SOD and EOC.  If the file ends before a delimiter is detected,
    the function returns 0. */

{
  hpbit_markers_ptr markers;
  hpbit_codestream_marker_ptr entry, last_entry;
  int byte_val, length, n;
  /* Begin Aerospace MCT mods (TSW) */
  /*  std_byte start[4];*/
  std_byte start[6];
  int pre_len = 4;
  /* End Aerospace MCT mods */

  if (tp == NULL)
    markers = &(self->global_markers);
  else
    markers = &(tp->markers);

⌨️ 快捷键说明

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