コード例 #1
0
ファイル: libics_compress.c プロジェクト: ikoryakovskiy/grl
/*
 * Read the full COMPRESS-compressed data stream.
 */
Ics_Error IcsReadCompress (Ics_Header* IcsStruct, void* outbuf, size_t len)
{
   ICSINIT;
   Ics_BlockRead* br = (Ics_BlockRead*)IcsStruct->BlockRead;
   unsigned char *stackp;
   long int code;
   int finchar;
   long int oldcode;
   long int incode;
   int inbits;
   int posbits;
   size_t outpos = 0;
   size_t insize;
   int bitmask;
   long int free_ent;
   long int maxcode;
   long int maxmaxcode;
   int n_bits;
   size_t rsize;
   int block_mode;
   int maxbits;
   int ii;
   int offset;
   unsigned char *inbuf = NULL;
   unsigned char *htab = NULL;
   unsigned short *codetab = NULL;

   /* Dynamically allocate memory that's static in (N)compress. */
   inbuf = (unsigned char*)malloc (IBUFSIZ+IBUFXTRA);
   if (inbuf == NULL) {
      error = IcsErr_Alloc;
      goto error_exit;
   }
   htab = (unsigned char*)malloc (HSIZE*4); /* Not sure about the size of this thing, original code uses a long int array that's cast to char */
   if (htab == NULL) {
      error = IcsErr_Alloc;
      goto error_exit;
   }
   codetab = (unsigned short*)malloc (HSIZE*sizeof(unsigned short));
   if (codetab == NULL) {
      error = IcsErr_Alloc;
      goto error_exit;
   }

   if ((rsize = fread(inbuf, 1, IBUFSIZ, br->DataFilePtr)) <= 0) {
      error = IcsErr_FReadIds;
      goto error_exit;
   }
   insize = rsize;
   if (insize < 3 || inbuf[0] != MAGIC_1 || inbuf[1] != MAGIC_2) {
      printf("point 1!\n");
      error = IcsErr_CorruptedStream;
      goto error_exit;
   }

   maxbits = inbuf[2] & BIT_MASK;
   block_mode = inbuf[2] & BLOCK_MODE;
   maxmaxcode = MAXCODE(maxbits);
   if (maxbits > BITS) {
      error = IcsErr_DecompressionProblem;
      goto error_exit;
   }

   maxcode = MAXCODE(n_bits = INIT_BITS)-1;
   bitmask = (1<<n_bits)-1;
   oldcode = -1;
   finchar = 0;
   posbits = 3<<3;

   free_ent = ((block_mode) ? FIRST : 256);

   clear_tab_prefixof();   /* As above, initialize the first 256 entries in the table. */
   for (code = 255 ; code >= 0 ; --code) {
      tab_suffixof(code) = (unsigned char)code;
   }

   do {
resetbuf:

      offset = posbits >> 3;
      insize = offset <= insize ? insize - offset : 0;
      for (ii = 0 ; ii < insize ; ++ii) {
         inbuf[ii] = inbuf[ii+offset];
      }
      posbits = 0;

      if (insize < IBUFXTRA) {
         rsize = fread(inbuf+insize, 1, IBUFSIZ, br->DataFilePtr);
         if (rsize <= 0 && !feof(br->DataFilePtr)) {
            error = IcsErr_FReadIds;
            goto error_exit;
         }
         insize += rsize;
      }

      inbits = ((rsize > 0) ? (insize - insize%n_bits)<<3 : (insize<<3)-(n_bits-1));

      while (inbits > posbits) {
         if (free_ent > maxcode) {
            posbits = ((posbits-1) + ((n_bits<<3) - (posbits-1+(n_bits<<3))%(n_bits<<3)));
            ++n_bits;
            if (n_bits == maxbits) {
               maxcode = maxmaxcode;
            }
            else {
               maxcode = MAXCODE(n_bits)-1;
            }
            bitmask = (1<<n_bits)-1;
            goto resetbuf;
         }

         input(inbuf,posbits,code,n_bits,bitmask);

         if (oldcode == -1) {
            if (code >= 256) {
               printf("point 3!\n");
               error = IcsErr_CorruptedStream;
               goto error_exit;
            }
            ((unsigned char*)outbuf)[outpos++] = (unsigned char)(finchar = (int)(oldcode = code));
            continue;
         }

         if (code == CLEAR && block_mode) {
            clear_tab_prefixof();
            free_ent = FIRST - 1;
            posbits = ((posbits-1) + ((n_bits<<3) - (posbits-1+(n_bits<<3))%(n_bits<<3)));
            maxcode = MAXCODE(n_bits = INIT_BITS)-1;
            bitmask = (1<<n_bits)-1;
            goto resetbuf;
         }

         incode = code;
         stackp = de_stack;

         if (code >= free_ent) { /* Special case for KwKwK string.   */
            if (code > free_ent) {
               printf("point 4!\n");
               error = IcsErr_CorruptedStream;
               goto error_exit;
            }
            *--stackp = (unsigned char)finchar;
            code = oldcode;
         }

         /* Generate output characters in reverse order */
         while (code >= 256) {
            *--stackp = tab_suffixof(code);
            code = tab_prefixof(code);
         }
         *--stackp = (unsigned char)(finchar = tab_suffixof(code));

         /* And put them out in forward order */
         ii = de_stack-stackp;
         if (outpos+ii > len) {
            ii = len-outpos; /* do not write more in buffer than fits! */
         }
         memcpy(((unsigned char*)outbuf)+outpos, stackp, ii);
         outpos += ii;
         if (outpos == len) {
            goto error_exit;
         }

         if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */
            tab_prefixof(code) = (unsigned short)oldcode;
            tab_suffixof(code) = (unsigned char)finchar;
            free_ent = code+1;
         } 

         oldcode = incode; /* Remember previous code. */
      }

   } while (rsize > 0);
   
   if (outpos != len) {
      error = IcsErr_OutputNotFilled;
   }

error_exit:
   /* Deallocate stuff */
   if (inbuf) free(inbuf);
   if (htab) free(htab);
   if (codetab) free(codetab);
   return error;
}
コード例 #2
0
ファイル: uncompress.c プロジェクト: bithorder/libxmp
int decrunch_compress(xmp_file in, xmp_file out)
{
	char_type *stackp;
	code_int code;
	int finchar;
	code_int oldcode;
	code_int incode;
	int inbits;
	int posbits;
	int outpos;
	int insize;
	int bitmask;
	code_int free_ent;
	code_int maxcode;
	code_int maxmaxcode;
	int n_bits;
	int rsize;
	int maxbits;
	int block_mode;
	int i;

	long bytes_in;			/* Total number of byte from input */
	long bytes_out;			/* Total number of byte to output */
	char_type inbuf[IBUFSIZ + 64];	/* Input buffer */
	char_type outbuf[OBUFSIZ + 2048];/* Output buffer */
	count_int htab[HSIZE];
	unsigned short codetab[HSIZE];

	bytes_in = 0;
	bytes_out = 0;
	insize = 0;

	rsize = xmp_fread(inbuf, 1, IBUFSIZ, in);
	insize += rsize;

	if (insize < 3 || inbuf[0] != MAGIC_1 || inbuf[1] != MAGIC_2) {
		return -1;
	}

	maxbits = inbuf[2] & BIT_MASK;
	block_mode = inbuf[2] & BLOCK_MODE;
	maxmaxcode = MAXCODE(maxbits);

	if (maxbits > BITS) {
		/*fprintf(stderr,
		   "%s: compressed with %d bits, can only handle %d bits\n",
		   (*ifname != '\0' ? ifname : "stdin"), maxbits, BITS);
		   exit_code = 4; */
		return -1;
	}

	bytes_in = insize;
	maxcode = MAXCODE(n_bits = INIT_BITS) - 1;
	bitmask = (1 << n_bits) - 1;
	oldcode = -1;
	finchar = 0;
	outpos = 0;
	posbits = 3 << 3;

	free_ent = ((block_mode) ? FIRST : 256);

	clear_tab_prefixof();	/* As above, initialize the first
				   256 entries in the table. */

	for (code = 255; code >= 0; --code)
		tab_suffixof(code) = (char_type) code;

	do {
	      resetbuf:;
		{
			int i;
			int e;
			int o;

			o = posbits >> 3;
			e = o <= insize ? insize - o : 0;

			for (i = 0; i < e; ++i)
				inbuf[i] = inbuf[i + o];

			insize = e;
			posbits = 0;
		}

		if (insize < sizeof(inbuf) - IBUFSIZ) {
			if ((rsize = xmp_fread(inbuf + insize, 1, IBUFSIZ, in)) < 0)
				return -1;

			insize += rsize;
		}

		inbits = ((rsize > 0) ? (insize - insize % n_bits) << 3 :
			  (insize << 3) - (n_bits - 1));

		while (inbits > posbits) {
			if (free_ent > maxcode) {
				posbits = ((posbits - 1) + ((n_bits << 3) -
							    (posbits - 1 +
							     (n_bits << 3)) %
							    (n_bits << 3)));

				++n_bits;
				if (n_bits == maxbits)
					maxcode = maxmaxcode;
				else
					maxcode = MAXCODE(n_bits) - 1;

				bitmask = (1 << n_bits) - 1;
				goto resetbuf;
			}

			input(inbuf, posbits, code, n_bits, bitmask);

			if (oldcode == -1) {
				if (code >= 256) {
					fprintf(stderr, "oldcode:-1 code:%i\n",
						(int)(code));
					fprintf(stderr, "uncompress: corrupt input\n");
					/* abort_compress(); */
					return -1;
				}
				outbuf[outpos++] = (char_type)(finchar = (int)(oldcode = code));
				continue;
			}

			if (code == CLEAR && block_mode) {
				clear_tab_prefixof();
				free_ent = FIRST - 1;
				posbits = ((posbits - 1) + ((n_bits << 3) -
					    (posbits - 1 + (n_bits << 3)) %
							   (n_bits << 3)));
				maxcode = MAXCODE(n_bits = INIT_BITS) - 1;
				bitmask = (1 << n_bits) - 1;
				goto resetbuf;
			}

			incode = code;
			stackp = de_stack;

			if (code >= free_ent) {	/* Special case for KwKwK string. */
				if (code > free_ent) {
					/*char_type *p;

					posbits -= n_bits;
					p = &inbuf[posbits >> 3];

					fprintf(stderr,
						"insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)\n",
						insize, posbits, p[-1], p[0],
						p[1], p[2], p[3],
						(posbits & 07));*/
					fprintf(stderr,
						"uncompress: corrupt input\n");
					/* abort_compress(); */
					return -1;
				}

				*--stackp = (char_type) finchar;
				code = oldcode;
			}

			while ((cmp_code_int) code >= (cmp_code_int) 256) {	/* Generate output characters in reverse order */
				*--stackp = tab_suffixof(code);
				code = tab_prefixof(code);
			}

			*--stackp = (char_type) (finchar = tab_suffixof(code));

			/* And put them out in forward order */

			if (outpos + (i = (de_stack - stackp)) >= OBUFSIZ) {
				do {
					if (i > OBUFSIZ - outpos)
						i = OBUFSIZ - outpos;

					if (i > 0) {
						memcpy(outbuf + outpos, stackp, i);
						outpos += i;
					}

					if (outpos >= OBUFSIZ) {
						if (xmp_fwrite(outbuf, 1, outpos, out) != outpos) {
							return -1;
							/*write_error(); */
						}

						outpos = 0;
					}
					stackp += i;
				}
				while ((i = (de_stack - stackp)) > 0);
			} else {
				memcpy(outbuf + outpos, stackp, i);
				outpos += i;
			}

			if ((code = free_ent) < maxmaxcode) {	/* Generate the new entry. */
				tab_prefixof(code) = (unsigned short)oldcode;
				tab_suffixof(code) = (char_type) finchar;
				free_ent = code + 1;
			}

			oldcode = incode;	/* Remember previous code.      */
		}

		bytes_in += rsize;
	}
	while (rsize > 0);

	if (outpos > 0 && xmp_fwrite(outbuf, 1, outpos, out) != outpos)
		return -1;

	return 0;
}