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

📄 hpbit_stream_in.c

📁 关于视频压缩的jpeg2000压缩算法,C编写
💻 C
📖 第 1 页 / 共 5 页
字号:
          {            assert(elt->size == 1);            tp->eph = (int) elt->buf[0];          }      }  }  return(1);}/*****************************************************************************//* STATIC             consume_anticipated_resync_marker                      *//*****************************************************************************/static int  consume_anticipated_resync_marker(hpbit_stream_in_ref self,                                    int *end_of_tilepart) /* This function expects to find a resync marker (SOP) with the correct    packet sequence index or else run into the end of the current tile-part    (possibly by reaching the end of the file).  If successful, the    `self->missing_packets' field remains zero and the function returns 1.    Otherwise, the function keeps reading until the next valid resync marker    or the end of the tile-part, and sets the `self->missing_packets' field    to hold the number of missing packets, as estimated from the next valid    resync marker.  In this case the function returns 0.  The number of    missing packets may still appear to be 0, because the sequence indices    align.  This generally means that the previous packet was not completely    read, but this might not be the case.        Before returning, the function sets *`end_of_tilepart' to 1 or 0,    depending upon whether or not the end of the current tile-part was    reached before encountering a resync marker.  It is the caller's    responsibility to advance to the next tile-part, set its sequence index    as appropriate and then reinvoke this function to synchronize at the    start of the first packet of the new tile-part. */{  hpbit_tilepart_ptr tp;  int corrupt, byte_val;  std_ushort seq;  *end_of_tilepart = 0;  tp = self->current_tilepart;  assert(!self->missing_packets);  corrupt = 0;  byte_val = 0;  do {    while (byte_val != 0x00FF)      {        byte_val = fetch_data_byte(self,tp);        if (byte_val == EOF)          break;        if (byte_val != 0x00FF)          corrupt = 1;      }    if ((byte_val == EOF) ||        ((byte_val=fetch_data_byte(self,tp)) == EOF))      { /* Reached the end of the tile-part. */        *end_of_tilepart = 1;        return(!corrupt);      }    if ((byte_val == (MARKER_SOT  & 0x00FF)) ||        (byte_val == (MARKER_EOI & 0x00FF)))      { /* Same as processing EOF except that we have encountered the           end of the tile-part prematurely, so we will have to correct           some length fields which were set at the start of the tile in           anticipation of an incorrect tile length. */        *end_of_tilepart = 1;        assert(tp->data == NULL); /* Must be reading from a file. */        assert(!self->have_sot);        if (byte_val == (MARKER_SOT & 0x00FF))          self->have_sot = 1;        tp->data_bytes -= tp->data_bytes_left+2;        self->non_data_bytes_left += tp->data_bytes_left;        tp->data_bytes_left = 0;        return(!corrupt);      }    else if (byte_val != (MARKER_SOP & 0x00FF))      corrupt = 1;  } while (byte_val != (MARKER_SOP & 0x00FF));  /* Read the packet sequence index and compare. */  byte_val = fetch_data_byte(self,tp);  seq = byte_val;  if ((byte_val == EOF) || ((byte_val = fetch_data_byte(self,tp)) == EOF))    { /* Reached the end of the tile-part. */      *end_of_tilepart = 1;      return(!corrupt);    }  seq <<= 8; seq |= (byte_val & 0x00FF);  if (corrupt || (seq != tp->packet_sequence_idx))    { /* Later we will need to fix this to anticipate the possibility of         corrupted sequence indices. */      self->missing_packets = ((int) seq) - ((int)(tp->packet_sequence_idx));      if (self->missing_packets < 0)        self->missing_packets += (1<<16);      return(0);    }  return(1);}/*****************************************************************************//* STATIC                consume_anticipated_eph_marker                      *//*****************************************************************************/static int  consume_anticipated_eph_marker(hpbit_stream_in_ref self,                                 hpbit_tilepart_ptr tp) /* Expects the next two bytes in the current packet to hold an EPH    marker.  Reads until the EPH marker is recovered regardless.    Returns 1 if the EPH marker is found.  Returns 0 if the end of    the file or tile-part is encountered or reading stopped due to    encountering an unexpected SOP marker; in the latter case, the    number of missing packets is also set, exactly as if the premature SOP    marker had been encountered within a call to `pull_packet_bytes'.    In the special case of packed packet headers, the function invariably    returns 1, since we do not want to prevent any reading of the    packet body in the event that a packet header was corrupted. */{  int byte_val;  hpbit_packed_head_ptr ph;  assert(tp->eph && !self->eph_found);  byte_val = 0;  if ((ph = tp->packed_heads) != NULL)    {      int have_ff;      self->eph_found = 1;      do {        have_ff = (byte_val == 0x00FF);        while ((ph->bytes_left == 0) && (ph->next != NULL))          {            tp->packed_heads = ph->next;            if (ph->data_handle != NULL)              local_free(ph->data_handle);            local_free(ph);            ph = tp->packed_heads;          }        if (ph->bytes_left == 0)          return(1);        byte_val = *(ph->data++);        ph->bytes_left--;      } while ((!have_ff) || (byte_val != (MARKER_EPH & 0x00FF)));      return(1);    }  do {    if (byte_val != 0x00FF)      {        if ((byte_val = fetch_data_byte(self,tp)) == EOF)          return(0);        self->packet_bytes++;      }    if (byte_val != 0x00FF)      continue;    if ((byte_val = fetch_data_byte(self,tp)) == EOF)      return(0);    self->packet_bytes++;    if ((byte_val == (MARKER_EOI & 0x00FF)) ||        (byte_val == (MARKER_SOT & 0x00FF)))      { /* We appear to have run into the end of the tile-part           prematurely.  Treat like encountering the end of the           tile-part normally, except that counters need to be           corrected. */        assert(tp->data == NULL); /* Must be reading from a file. */        assert(!self->have_sot);        if (byte_val == (MARKER_SOT & 0x00FF))          self->have_sot = 1;        tp->data_bytes -= tp->data_bytes_left+2;        self->non_data_bytes_left += tp->data_bytes_left;        tp->data_bytes_left = 0;        return(0);      }    else if (tp->resync && (byte_val == (MARKER_SOP & 0x00FF)))      { /* We appear to have run into the next packet. */        std_ushort seq;        byte_val = fetch_data_byte(self,tp);        if (byte_val == EOF)          return(0);        seq = byte_val;        byte_val = fetch_data_byte(self,tp);        if (byte_val == EOF)          return(0);        seq <<= 8; seq |= byte_val;        self->missing_packets =          ((int) seq) - ((int)(tp->packet_sequence_idx));        if (self->missing_packets < 0)          self->missing_packets += 1<<16;        self->missing_packets++; /* Rest of current packet missing */        return(0);      }  } while (byte_val != (MARKER_EPH & 0x00FF));  self->eph_found = 1;  return(1);}/*****************************************************************************//* STATIC                    advance_current_tilepart                        *//*****************************************************************************/static void  advance_current_tilepart(hpbit_stream_in_ref self) /* Advances from the tile-part identified by `self->current_tilepart' to    the next non-empty tile-part in sequence, reading tile-part headers as    necessary.  Note that the relevant tile-part's header and even its body    may already have been read.  If there are no more tile-parts,    the `current_tilepart' pointer is set to NULL.  Storage managed by    the previous tile-part may be released at this point. */{  hpbit_tilepart_ptr tp;  int code, empty_tilepart;  empty_tilepart = 0;  do {    tp = self->current_tilepart;    if (tp == NULL)      tp = self->tileparts;    else      {        hpbit_packed_head_ptr packed;        destroy_markers(&(tp->markers),tp);        if  (tp->data_handle != NULL)          local_free(tp->data_handle);        tp->data_handle = tp->data = NULL;        while ((packed = tp->packed_heads) != NULL)          {            tp->packed_heads = packed->next;            if (packed->data_handle != NULL)              local_free(packed->data_handle);            local_free(packed);          }        tp = tp->next;      }    if (tp == NULL)      { /* Read a new tile-part header. */        do {          code = read_new_tilepart_header(self);        } while (code < 0);        if (code == 0)          { /* Reached the end of the codestream. */            self->current_tilepart = NULL;            return;          }      }    tp = self->current_tilepart;    if (tp == NULL)      tp = self->tileparts;    else      tp = tp->next;    assert(tp != NULL);    self->current_tilepart = tp;    self->missing_packets = 0;    if (tp->last_part != NULL)      tp->packet_sequence_idx = tp->last_part->packet_sequence_idx;    if (tp->resync)      consume_anticipated_resync_marker(self,&empty_tilepart);  } while (empty_tilepart);  self->virgin_tilepart = 1;}/*****************************************************************************//* STATIC                      pull_packet_bytes                             *//*****************************************************************************/static int  pull_packet_bytes(hpbit_stream_in_ref self, std_byte *buf, int num_bytes,                    int in_head) /* Under normal circumstances, this function does most of the work of    `__pull_head_bytes' and `__pull_body_bytes'. */{  hpbit_tilepart_ptr tp;  int result, byte_val;  assert(self->open_packet);  tp = self->current_tilepart;  if (self->missing_packets)    return(0);  for (result=0; num_bytes > 0; num_bytes--, result++)    {      if ((byte_val = fetch_data_byte(self,tp)) == EOF)        return(result);      if (byte_val == 0x00FF)        {          byte_val = fetch_data_byte(self,tp);          if (byte_val == EOF)            { /* We have run into the end of the tile-part. */              return(result);            }          else if ((byte_val == (MARKER_EOI & 0x00FF)) ||                   (byte_val == (MARKER_SOT & 0x00FF)))            { /* We appear to have run into the end of the tile-part                 prematurely.  Treat like encountering the end of the                 tile-part normally, except that counters need to be                 corrected. */              assert(tp->data == NULL); /* Must be reading from a file. */              assert(!self->have_sot);              if (byte_val == (MARKER_SOT & 0x00FF))                self->have_sot = 1;              tp->data_bytes -= tp->data_bytes_left+2;              self->non_data_bytes_left += tp->data_bytes_left;              tp->data_bytes_left = 0;              return(result);            }          else if (tp->resync && (byte_val == (MARKER_SOP & 0x00FF)))            { /* We appear to have run into the next packet. */              std_ushort seq;              byte_val = fetch_data_byte(self,tp);              if (byte_val == EOF)                return(result);              seq = byte_val;              byte_val = fetch_data_byte(self,tp);              if (byte_val == EOF)                return(result);              seq <<= 8; seq |= byte_val;              self->missing_packets =                ((int) seq) - ((int)(tp->packet_sequence_idx));              if (self->missing_packets < 0)                self->missing_packets += 1<<16;              self->missing_packets++; /* Rest of current packet missing */              return(result);            }          else if ((byte_val == (MARKER_EPH & 0x00FF)) &&                   tp->eph && !self->eph_found)            { /* Skip over the EPH marker. */              self->eph_found = 1;              num_bytes++;              result--;              self->packet_bytes += 2;              continue;            }          else            { /* Treat marker as part of packet stream. */              return_data_byte(self,tp,byte_val);              byte_val = 0x00FF;            }        }      *(buf++) = (std_byte) byte_val;      self->packet_bytes++;    }  return(result);}  /* ========================================================================= *//* ------------------------- Interface Implementation ---------------------- *//* ========================================================================= *//*****************************************************************************//* STATIC                         __initialize                               *//*****************************************************************************/static void  __initialize(stream_in_ref base, char *filename, cmdl_ref cmdl){  hpbit_stream_in_ref self = (hpbit_stream_in_ref) base;  std_ushort soc;  std_ushort delimiter;  int byte_val;  self->fp = fopen(filename,"rb");  if (self->fp == NULL)    local_error("Unable to open input file, \"%s\"!",filename);  byte_val = fetch_non_data_byte(self);  soc = (std_ushort ) byte_val;  byte_val = fetch_non_data_byte(self);  soc = (soc <<8) | (std_ushort) byte_val;  if ((byte_val == EOF) || (soc != MARKER_SOC))    local_error("Input codestream does not commence with the SOC marker!");  self->global_markers.total_codestream_bytes = 2;  delimiter = read_markers(self,NULL);  if (delimiter != MARKER_SOT)    local_error("I

⌨️ 快捷键说明

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