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

📄 pclcomp.c

📁 openmeetings组件之GS openmeetings组件之GS openmeetings组件之GS
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Treat the special case of a zero output buffer (actually, the bad case is     merely the one where 'out' is NULL) */  if (maxoutcount == 0) {    if (incount == prevcount &&      (incount == 0 || memcmp(in, prev, incount) == 0)) return 0;      /* Can there be machines where memcmp() compares bits beyond those	 used for the 'pcl_Octet's? Unlikely. */    return -1;  }  /* Initialization */  mincount = (incount < prevcount? incount: prevcount);  pos = 0; opos = 0;  absoffset = 0;	/* first untreated octet, i.e. position after the last			   unaltered octet. */  /* Loop over parts common to this and the last row */  delta_loop(mincount, in[pos], prev[pos], in + absoffset);  /*  Note: This artificial separation at the 'mincount' position (logically,      both rows have equal length) is simpler to program but can result in      the compressed row being 1 octet longer than necessary. */  /* Treat length differences between 'in' and 'prev'. */  if (mincount < incount) {    /* We have to send all octets in the 'in' row which are non-zero. */    delta_loop(incount, in[pos], 0, in + absoffset);  }  else {    /* We have to replace all non-zero octets in the previous row. */    pcl_Octet zero_block[8] = {0, 0, 0, 0, 0, 0, 0, 0};    delta_loop(prevcount, 0, prev[pos], zero_block);  }  assert(opos <= maxoutcount);  return opos;}#undef delta_loop/******************************************************************************  Function: write_crdr_header  This function writes the header for compressed replacement delta row encoding  (method 9). It returns the number of octets written or a negative value on  error.******************************************************************************/static int write_crdr_header(pcl_bool compressed, pcl_Octet *out,  int maxoutcount, int reloffset, int repcount){  int    maxvalue,    shift,    used = 1;	/* command byte */  /* The command byte */  if (maxoutcount < 1) return -1;  if (compressed) *out = 0x80;	/* control bit: compressed */  else *out = 0;		/* control bit: uncompressed */  maxvalue = (compressed? 3: 15);  shift = (compressed? 5: 3);  if (reloffset < maxvalue) {    *out += reloffset << shift;    reloffset = -1;  }  else {    *out += maxvalue << shift;    reloffset -= maxvalue;  }  /* The value to be encoded for 'repcount' is different from 'repcount': */  if (compressed) repcount -= 2;  else repcount--;  assert(repcount >= 0);  maxvalue = (compressed? 31: 7);  if (repcount < maxvalue) {    *out += repcount;    repcount = -1;  }  else {    *out += maxvalue;    repcount -= maxvalue;  }  out++;  /* Optional offset bytes */  while (reloffset >= 0) {    if (used >= maxoutcount) return -1;    *out++ = (reloffset >= 255? 255: reloffset);    reloffset -= 255;    used++;  }  /* Optional replacement count bytes */  while (repcount >= 0) {    if (used >= maxoutcount) return -1;    *out++ = (repcount >= 255? 255: repcount);    repcount -= 255;    used++;  }  return used;}/******************************************************************************  Function: write_crdr_uncompressed  This function returns the number of octets written or a negative value on  error.  'in' may be NULL, indicating a sequence of 'repcount' null octets.  This case is practically irrelevant except for 'repcount' == 1.******************************************************************************/static int write_crdr_uncompressed(pcl_Octet *out, int maxoutcount,  int reloffset, const pcl_Octet *in, int repcount){  int used = write_crdr_header(FALSE, out, maxoutcount, reloffset, repcount);  if (used < 0 || used + repcount > maxoutcount) return -1;  out += used;  if (in == NULL) memset(out, 0, repcount*sizeof(pcl_Octet));  else memcpy(out, in, repcount*sizeof(pcl_Octet));  return used + repcount;}/******************************************************************************  Function: write_crdr_compressed  This function returns the number of octets written or a negative value on  error.******************************************************************************/static int write_crdr_compressed(pcl_Octet *out, int maxoutcount, int reloffset,  pcl_Octet in, int repeat_count){  int used = write_crdr_header(TRUE, out, maxoutcount, reloffset, repeat_count);  if (used < 0 || used >= maxoutcount) return -1;  out += used;  *out = in;  return used + 1;}/******************************************************************************  Function: write_crdr_replacement  This function returns the number of octets written to 'out' or a negative  value on error.  'in' may be NULL, indicating a sequence of 'repcount' null octets.  'repcount' must be positive.******************************************************************************/static int write_crdr_replacement(pcl_Octet *out, int maxoutcount,  int reloffset, const pcl_Octet *in, int repcount){  const pcl_Octet *final;  int written = 0;  /* Treat the case of a null sequence */  if (in == NULL) {    if (repcount == 1)      return write_crdr_uncompressed(out, maxoutcount, reloffset, in, repcount);    return write_crdr_compressed(out, maxoutcount, reloffset, 0, repcount);  }  /* Loop over 'in', dividing it into sections at the boundaries of     sequences of repeated octets. */  final = in + repcount - 1;  while (repcount > 0) {    /* Advance 'bdup' over non-repeated octet */    const pcl_Octet *bdup;    bdup = in;    while (bdup < final && *bdup != *(bdup + 1)) bdup++;    /* If there is something either before a repeated section or before the       end, encode it uncompressed. */    if (in < bdup || bdup == final) {      int incount = (bdup == final? repcount: bdup - in);      int rc;      rc = write_crdr_uncompressed(out + written, maxoutcount - written,	reloffset, in, incount);      if (rc < 0) return rc;      written += rc;      reloffset = 0;      repcount -= incount;      if (repcount > 0) in += incount;    }    /* If we have encountered a repeated section, encode it compressed.       Note that the compressed version for a repetition is never longer than       the uncompressed one, not even for a repeat count of 2, although in this       case it might have equal length depending on the offset. */    if (bdup < final) {      const pcl_Octet *edup = bdup + 1;      int incount, rc;      while (edup < final && *(edup + 1) == *bdup) edup++;      incount = edup - bdup + 1;      rc = write_crdr_compressed(out + written, maxoutcount - written,	reloffset, *bdup, incount);      if (rc < 0) return rc;      written += rc;      reloffset = 0;      repcount -= incount;      if (repcount > 0) in = edup + 1;    }  }  return written;}/******************************************************************************  Function: compress_crdr  This function performs compressed replacement delta row encoding (compression  method 9).  The pairs (in, incount) and (prev, prevcount) describe the row to be  compressed and the row sent last (seed row), of course in uncompressed  form. (out, maxcount) refers to a storage area of 'maxoutcount' length to  which the compressed result for 'in' is to be written.  All three octet strings must be valid and any may be zero.  It is assumed that any difference in length between 'in' and 'prev' is  (logically) due to trailing zero octets having been suppressed in the shorter  of the two.  The function returns the number of octets written to 'out' (a zero value is  possible and refers to a row identical with the one sent last), or a negative  value on error.  This function and those it calls are very similar to the functions for delta  row compression.******************************************************************************//*  Again, as for delta row compression, I'm using a macro for comparison. */#define crdr_loop(bound, invalue, prevvalue, repstart)			\  while (pos < bound) {							\    if (invalue == prevvalue) pos++;					\    else {								\      int reloffset = pos - absoffset, written;				\      absoffset = pos;							\      do pos++; while (pos < bound && invalue != prevvalue);		\									\      written = write_crdr_replacement(out + opos, maxoutcount - opos,	\	reloffset, repstart, pos - absoffset);				\      if (written < 0) return written;					\      absoffset = pos;							\      opos += written;							\    }									\  }static int compress_crdr(const pcl_Octet *in, int incount,  const pcl_Octet *prev, int prevcount, pcl_Octet *out, int maxoutcount){  int    absoffset = 0,    mincount = (incount < prevcount? incount: prevcount),    opos = 0,    pos = 0;  /* Treat the special case of a zero output buffer (again, the bad case is     merely the one where 'out' is NULL) */  if (maxoutcount == 0) {    if (incount == prevcount &&      (incount == 0 || memcmp(in, prev, incount) == 0)) return 0;    return -1;  }  crdr_loop(mincount, in[pos], prev[pos], in + absoffset);  if (mincount < incount) {    crdr_loop(incount, in[pos], 0, in + absoffset);  }  else {    crdr_loop(prevcount, 0, prev[pos], NULL);  }  return opos;}#undef crdr_loop/******************************************************************************  Function: pcl_compress  This function compresses an octet string using the compression algorithm  specified by 'method'.  The arguments 'in' and 'out' must be non-NULL. They point to the data to be  compressed ('in->length' octets starting at 'in->str') and the area to which  the compressed result should be written (at most 'out->length' octets  starting at 'out->str'). If '*in' and '*out' are both non-zero (see  definitions above), their storage areas ('in->str' to  'in->str + in->length - 1' and 'out->str' to 'out->str + out->length - 1')  should not overlap.  If 'method' refers to a method entailing "vertical" compression, i.e.  compression with respect to an octet string previously sent, 'prev' must  point to this previous string. This is the case for methods 3 and 9.  The variable is ignored otherwise and may be NULL. If it is needed, it should  not overlap with the storage area of '*out'.  The function returns a non-zero value in case of insufficient space in '*out'.  In that situation, part of 'out->str' may have been overwritten already.  Otherwise, a value of zero is returned and 'out->length' is set to the number  of octets the compressed result occupies in 'out->str'.******************************************************************************//* Test macro for an argument of type "pcl_OctetString *" */#define is_valid(s)	\  (s != NULL && ((s)->length == 0 || (s)->length > 0 && (s)->str != NULL))int pcl_compress(pcl_Compression method, const pcl_OctetString *in,  const pcl_OctetString *prev, pcl_OctetString *out){  int result = -1;  /* Prevent silly mistakes with the arguments */  assert(is_valid(in) && is_valid(out) &&    (method != pcl_cm_delta && method != pcl_cm_crdr || is_valid(prev)));  /* Treat zero-length case for the "purely horizontal" methods */  if (in->length == 0 && method != pcl_cm_delta && method != pcl_cm_crdr) {    out->length = 0;    return 0;  }  switch (method) {  case pcl_cm_none:	/* oh, well... */    if (out->length <= in->length) {      memcpy(out->str, in->str, in->length*sizeof(pcl_Octet));      result = in->length;    }    break;  case pcl_cm_rl:    result = compress_runlength(in->str, in->length, out->str, out->length);    break;  case pcl_cm_tiff:    result = compress_tiff(in->str, in->length, out->str, out->length);    break;  case pcl_cm_delta:    result = compress_delta(in->str, in->length, prev->str, prev->length,      out->str, out->length);    break;  case pcl_cm_crdr:    result = compress_crdr(in->str, in->length, prev->str, prev->length,      out->str, out->length);    break;  default:    assert(0);	/* Illegal value for compression method */    /* If NDEBUG is defined, we fall through with the default value for       'result' which is -1, i.e., failure. */  }  /* Assign the length of the output octet string */  if (result >= 0) {    out->length = result;    result = 0;  }  return result;}

⌨️ 快捷键说明

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