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

📄 hpbit_stream_in.c

📁 关于视频压缩的jpeg2000压缩算法,C编写
💻 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: VM6.0                                                            *//* Last Revised: 27 January, 2000                                            *//*****************************************************************************//*****************************************************************************//* 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.                                          *//*****************************************************************************/#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 SOS marker, up until the next SOT or EOI 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 EOI). */#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 EOI    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_EOI & 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);        }      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, SOS and EOI.  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;  std_byte start[4];  if (tp == NULL)    markers = &(self->global_markers);  else    markers = &(tp->markers);  last_entry = NULL;  do {    byte_val = 0;    while (byte_val != 0x00FF)      {        byte_val = fetch_non_data_byte(self);        if (byte_val == EOF)          return(0);      }    if ((byte_val = fetch_non_data_byte(self)) == EOF)      return(0);    if (byte_val == (MARKER_SOS & 0x00FF))      return(MARKER_SOS);    if (byte_val == (MARKER_SOT & 0x00FF))      {        self->have_sot = 1;        return(MARKER_SOT);      }    if (byte_val == (MARKER_EOI & 0x00FF))      return(MARKER_EOI);    start[0] = 0xFF;    start[1] = (std_byte) byte_val;    if ((byte_val = fetch_non_data_byte(self)) == EOF)      return(0);    start[2] = (std_byte) byte_val;    if ((byte_val = fetch_non_data_byte(self)) == EOF)      return(0);    start[3] = (std_byte) byte_val;        length = start[2];    length <<= 8; length += start[3];    length += 2; /* Length does not include the marker code itself. */    entry = (hpbit_codestream_marker_ptr)      local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_codestream_marker));    if (last_entry == NULL)      {        assert(markers->codestream_markers == NULL);        markers->codestream_markers = entry;      }    else      last_entry->next = entry;    last_entry = entry;    entry->buf = local_malloc(HPBIT_MEM_KEY,length);    for (n=0; n < 4; n++)      entry->buf[n] = start[n];

⌨️ 快捷键说明

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