codestream.cpp

来自「JPEG2000的C++实现代码」· C++ 代码 · 共 1,845 行 · 第 1/5 页

CPP
1,845
字号
  first_unread = first_unwritten = buffer + KD_IBUF_PUTBACK;  int xfer_bytes = KD_IBUF_SIZE - KD_IBUF_PUTBACK;  int buf_bytes;  while (xfer_bytes > 0)    {      if (read_pos == KD_CODE_BUFFER_LEN)        {          if (read_buf != write_buf)            {              read_buf = read_buf->next;              read_pos = 0;              assert(read_buf != NULL);            }        }      buf_bytes = (read_buf==write_buf)?write_pos:KD_CODE_BUFFER_LEN;      buf_bytes -= read_pos;      assert(buf_bytes >= 0);      if (buf_bytes == 0)        break;      if (buf_bytes > xfer_bytes)        buf_bytes = xfer_bytes;      xfer_bytes -= buf_bytes;      while (buf_bytes--)        *(first_unwritten++) = read_buf->buf[read_pos++];    }  if (first_unread == first_unwritten)    { exhausted = true; return false; }  return true;}/* ========================================================================= *//*                                 kd_marker                                 *//* ========================================================================= *//*****************************************************************************//*                        kd_marker::kd_marker (copy)                        *//*****************************************************************************/kd_marker::kd_marker(const kd_marker &orig){  source = NULL;  code = orig.code;  max_length = length = orig.length;  if (max_length == 0)    buf = NULL;  else    buf = new kdu_byte[max_length];  memcpy(buf,orig.buf,(size_t) length);}/*****************************************************************************//*                              kd_marker::read                              *//*****************************************************************************/bool  kd_marker::read(bool exclude_stuff_bytes, bool skip_to_marker){  assert(source != NULL);  kdu_byte byte = 0;  bool valid_code;  source->disable_marker_throwing();  do {      if ((byte != 0xFF) && !source->get(byte))        { code = 0; length = 0; return false; }      if (skip_to_marker)        while (byte != 0xFF)          if (!source->get(byte))            { code = 0; length = 0; return false; }      if (byte != 0xFF)        {          source->putback(byte);          code = 0; length = 0; return false;        }      if (!source->get(byte))        { code = 0; length = 0; return false; }      code = 0xFF00 + byte;      valid_code = true;      if (exclude_stuff_bytes)        valid_code = (byte > 0x8F);      if ((code == KDU_SOP) || (code == KDU_SOT))        { // Want to be really sure that this is not a corrupt marker code.          assert(valid_code);          if (!source->get(byte))            { code = 0; length = 0; return false; }          length = byte; length <<= 8;          if (!source->get(byte))            { code = 0; length = 0; return false; }          length += byte;          if ((code == KDU_SOP) && (length != 4))            {              valid_code = false;              source->putback((kdu_uint16) length);              kdu_warning w; w << "Skipping over corrupt SOP marker code!";            }          else if ((code == KDU_SOT) && (length != 10))            {              valid_code = false;              source->putback((kdu_uint16) length);              kdu_warning w;  w << "Skipping over corrupt SOT marker code!";            }          byte = (kdu_byte) code;        }      else if (code == KDU_EOC)        { /* If the input source is about to end, we will simply skip over             the EOC marker so that true EOC termination can be treated in             the same way as premature termination of the code-stream.             Otherwise, the EOC marker would appear to have been generated             by some type of code-stream corruption.  In this case, we will             treat it as an invalid marker code. */          if (source->get(byte))            {              valid_code = false;              source->putback(byte);              byte = (kdu_byte) code;              kdu_warning w; w << "Disregarding non-terminal EOC marker.";            }          else            { length = 0; code = 0; return false; }        }    } while (skip_to_marker && (!valid_code));  if (!valid_code)    {      source->putback(code);      code = 0; length = 0;      return false;    }  // Now we are committed to processing the marker, returning false only if  // the source becomes exhausted.  if ((code == KDU_SOC) || (code == KDU_SOD) ||      (code == KDU_EOC) || (code == KDU_EPH))    return true; // Delimiter found. There is no marker segment.  if ((code != KDU_SOT) && (code != KDU_SOP) && (code != KDU_SIZ) &&      (code != KDU_COD) && (code != KDU_COC) &&      (code != KDU_QCD) && (code != KDU_QCC) &&      (code != KDU_RGN) && (code != KDU_POC) &&      (code != KDU_CRG) && (code != KDU_COM) &&      (code != KDU_TLM) && (code != KDU_PLM) && (code != KDU_PLT) &&      (code != KDU_PPM) && (code != KDU_PPT))    {      kdu_warning w; w << "Unrecognized/unimplemented marker code, ";      print_current_code(w);  w << ", found in code-stream.";    }  if ((code != KDU_SOP) && (code != KDU_SOT))    { // Otherwise, we already have the length.      if (!source->get(byte))        { code = 0; return false; }      length = byte; length <<= 8;      if (!source->get(byte))        { code = 0; length = 0; return false; }      length += byte;    }  length -= 2;  if (length < 0)    { code = 0; length = 0; return false; }  if (length > max_length)    {      max_length = 2*length; // Don't want to have to re-allocate too often      delete[] buf;      buf = new kdu_byte[max_length];    }  if (source->read(buf,length) < length)    {      code = 0; length = 0;      return false;    }  return true;}/* ========================================================================= *//*                                kd_pp_markers                              *//* ========================================================================= *//*****************************************************************************//*                        kd_pp_markers::~kd_pp_markers                      *//*****************************************************************************/kd_pp_markers::~kd_pp_markers(){  kd_pp_marker_list *tmp;  while ((tmp=list) != NULL)    {      list = tmp->next;      delete tmp;    }}/*****************************************************************************//*                          kd_pp_markers::add_markers                       *//*****************************************************************************/void  kd_pp_markers::add_marker(kd_marker &copy_source){  if (copy_source.get_length() < 1)    { kdu_error e;      e << "PPM/PPT marker segments must be at least 3 bytes long!"; }  kd_pp_marker_list *elt = new kd_pp_marker_list(copy_source);  kdu_byte *data = elt->get_bytes();  elt->znum = data[0];  elt->bytes_read = 1;  if (elt->get_code() == KDU_PPM)    {      assert((list == NULL) || is_ppm);      is_ppm = true;    }  else    {      assert(elt->get_code() == KDU_PPT);      assert((list == NULL) || !is_ppm);      is_ppm = false;    }  kd_pp_marker_list *scan, *prev;  for (prev=NULL, scan=list; scan != NULL; prev=scan, scan=scan->next)    if (scan->znum > elt->znum)      break;  elt->next = scan;  if (prev == NULL)    list = elt;  else    {      prev->next = elt;      if (prev->znum == elt->znum)        { kdu_error e; e << "Found multiple PPM/PPT markers with identical "          "Zppt/Zppm indices within the same header scope (main or tile-part "          "header)!"; }    }}/*****************************************************************************//*                        kd_pp_markers::transfer_tpart                      *//*****************************************************************************/void  kd_pp_markers::transfer_tpart(kd_pph_input *pph_input){  int xfer_bytes = INT_MAX;  if (is_ppm)    {      while ((list != NULL) && (list->bytes_read == list->get_length()))        advance_list();      if (list == NULL)        { kdu_error e; e << "Insufficient packet header data in PPM marker "          "segments!"; }      if ((list->get_length()-list->bytes_read) < 4)        { kdu_error e; e << "Encountered malformed PPM marker: 4-byte Nppm "          "values may not straddle multiple PPM marker segments.  Problem "          "is most likely due to a previously incorrect Nppm value."; }      kdu_byte *data = list->get_bytes();      xfer_bytes = data[list->bytes_read++];      xfer_bytes = (xfer_bytes << 8) + data[list->bytes_read++];      xfer_bytes = (xfer_bytes << 8) + data[list->bytes_read++];      xfer_bytes = (xfer_bytes << 8) + data[list->bytes_read++];    }  while ((list != NULL) && (xfer_bytes > 0))    {      int elt_bytes = list->get_length()-list->bytes_read;      if (elt_bytes > xfer_bytes)        elt_bytes = xfer_bytes;      pph_input->add_bytes(list->get_bytes()+list->bytes_read,elt_bytes);      xfer_bytes -= elt_bytes;      list->bytes_read += elt_bytes;      if (list->bytes_read == list->get_length())        advance_list();    }  if (is_ppm && (xfer_bytes > 0))    { kdu_error e; e << "Insufficient packet header data in PPM marker "      "segments, or else Nppm values must be incorrect!"; }}/*****************************************************************************//*                         kd_pp_markers::ignore_tpart                       *//*****************************************************************************/void  kd_pp_markers::ignore_tpart(){  int xfer_bytes = INT_MAX;  if (is_ppm)    {      kdu_byte byte;      int len_bytes = 0;      while (len_bytes < 4)        { // Need to read 4 bytes of length information.          if (list == NULL)            { kdu_error e; e << "Insufficient packet header data in PPM "              "marker segments!"; }          if (list->bytes_read == list->get_length())            {              advance_list();              continue;            }          byte = (list->get_bytes())[list->bytes_read++];          xfer_bytes = (xfer_bytes << 8) + byte;          len_bytes++;        }    }  while ((list != NULL) && (xfer_bytes > 0))    {      int elt_bytes = list->get_length()-list->bytes_read;      if (elt_bytes > xfer_bytes)        elt_bytes = xfer_bytes;      xfer_bytes -= elt_bytes;      list->bytes_read += elt_bytes;      if (list->bytes_read == list->get_length())        advance_list();    }  if (is_ppm && (xfer_bytes > 0))    { kdu_error e; e << "Insufficient packet header data in PPM marker "      "segments, or else Nppm values must be incorrect!"; }}/*****************************************************************************//*                         kd_pp_markers::advance_list                       *//*****************************************************************************/void  kd_pp_markers::advance_list(){  assert((list != NULL) && (list->bytes_read == list->get_length()));  kd_pp_marker_list *tmp = list;  list = tmp->next;  delete tmp;}/* ========================================================================= *//*                               kd_buf_server                               *//* ========================================================================= *//*****************************************************************************//*                       kd_buf_server::~kd_buf_server                       *//*****************************************************************************/kd_buf_server::~kd_buf_server(){  assert(num_users == 0);  if (num_allocated_buffers != 0)    { kdu_warning w;  w << "The compressed data buffer server is being "      "destroyed before all allocated buffers have been returned.  The "      "problem is most likely connected with a bug in the code-block "      "destruction code."; }  kd_code_alloc *tmp;  while ((tmp=alloc) != NULL)    {      alloc = tmp->next;      delete tmp;    }}/*****************************************************************************//*                             kd_buf_server::get                            *//*****************************************************************************/kd_code_buffer *  kd_buf_server::get(){  if (free == NULL)    {      assert(num_allocated_buffers == total_buffers);

⌨️ 快捷键说明

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