Changeset 64bad829 in rtems for cpukit/zlib
- Timestamp:
- Jul 27, 2008, 6:58:53 PM (11 years ago)
- Branches:
- 4.10, 4.11, master
- Children:
- ced3e37
- Parents:
- d42bd2f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/zlib/contrib/puff/puff.c
rd42bd2f r64bad829 1 1 /* 2 2 * puff.c 3 * Copyright (C) 2002-200 4Mark Adler3 * Copyright (C) 2002-2008 Mark Adler 4 4 * For conditions of distribution and use, see copyright notice in puff.h 5 * version 1.8, 9 Jan 20045 * version 2.0, 25 Jul 2008 6 6 * 7 7 * puff.c is a simple inflate written to be an unambiguous way to specify the … … 62 62 * - Added zlib-like license 63 63 * 1.8 9 Jan 2004 - Added some comments on no distance codes case 64 * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland] 65 * - Catch missing end-of-block symbol error 66 * 2.0 25 Jul 2008 - Add #define to permit distance too far back 67 * - Add option in TEST code for puff to write the data 68 * - Add option in TEST code to skip input bytes 69 * - Allow TEST code to read from piped stdin 64 70 */ 65 71 … … 195 201 * a negative value if there is an error. If all of the lengths are zero, i.e. 196 202 * an empty code, or if the code is incomplete and an invalid code is received, 197 * then - 9is returned after reading MAXBITS bits.203 * then -10 is returned after reading MAXBITS bits. 198 204 * 199 205 * Format notes: … … 227 233 code |= bits(s, 1); /* get next bit */ 228 234 count = h->count[len]; 229 if (code < first + count) /* if length len, return symbol */235 if (code - count < first) /* if length len, return symbol */ 230 236 return h->symbol[index + (code - first)]; 231 237 index += count; /* else update for next length */ … … 234 240 code <<= 1; 235 241 } 236 return - 9;/* ran out of codes */242 return -10; /* ran out of codes */ 237 243 } 238 244 … … 264 270 bitbuf >>= 1; 265 271 count = *next++; 266 if (code < first + count) { /* if length len, return symbol */272 if (code - count < first) { /* if length len, return symbol */ 267 273 s->bitbuf = bitbuf; 268 274 s->bitcnt = (s->bitcnt - len) & 7; … … 281 287 if (left > 8) left = 8; 282 288 } 283 return - 9;/* ran out of codes */289 return -10; /* ran out of codes */ 284 290 } 285 291 #endif /* SLOW */ … … 449 455 /* get and compute length */ 450 456 symbol -= 257; 451 if (symbol >= 29) return - 9;/* invalid fixed code */457 if (symbol >= 29) return -10; /* invalid fixed code */ 452 458 len = lens[symbol] + bits(s, lext[symbol]); 453 459 … … 456 462 if (symbol < 0) return symbol; /* invalid symbol */ 457 463 dist = dists[symbol] + bits(s, dext[symbol]); 464 #ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 458 465 if (dist > s->outcnt) 459 return -10; /* distance too far back */ 466 return -11; /* distance too far back */ 467 #endif 460 468 461 469 /* copy length bytes from distance bytes back */ … … 463 471 if (s->outcnt + len > s->outlen) return 1; 464 472 while (len--) { 465 s->out[s->outcnt] = s->out[s->outcnt - dist]; 473 s->out[s->outcnt] = 474 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 475 dist > s->outcnt ? 0 : 476 #endif 477 s->out[s->outcnt - dist]; 466 478 s->outcnt++; 467 479 } … … 681 693 } 682 694 695 /* check for end-of-block code -- there better be one! */ 696 if (lengths[256] == 0) 697 return -9; 698 683 699 /* build huffman table for literal/length codes */ 684 700 err = construct(&lencode, lengths, nlen); … … 725 741 * -7: dynamic block code description: invalid literal/length code lengths 726 742 * -8: dynamic block code description: invalid distance code lengths 727 * -9: invalid literal/length or distance code in fixed or dynamic block 728 * -10: distance is too far back in fixed or dynamic block 743 * -9: dynamic block code description: missing end-of-block code 744 * -10: invalid literal/length or distance code in fixed or dynamic block 745 * -11: distance is too far back in fixed or dynamic block 729 746 * 730 747 * Format notes: … … 784 801 785 802 #ifdef TEST 786 /* Example of how to use puff() */ 803 /* Examples of how to use puff(). 804 805 Usage: puff [-w] [-nnn] file 806 ... | puff [-w] [-nnn] 807 808 where file is the input file with deflate data, nnn is the number of bytes 809 of input to skip before inflating (e.g. to skip a zlib or gzip header), and 810 -w is used to write the decompressed data to stdout */ 811 787 812 #include <stdio.h> 788 813 #include <stdlib.h> 789 #include <sys/types.h> 790 #include <sys/stat.h> 791 792 local unsigned char *yank(char *name, unsigned long *len) 793 { 794 unsigned long size; 795 unsigned char *buf; 814 815 /* Return size times approximately the cube root of 2, keeping the result as 1, 816 3, or 5 times a power of 2 -- the result is always > size, until the result 817 is the maximum value of an unsigned long, where it remains. This is useful 818 to keep reallocations less than ~33% over the actual data. */ 819 local size_t bythirds(size_t size) 820 { 821 int n; 822 size_t m; 823 824 m = size; 825 for (n = 0; m; n++) 826 m >>= 1; 827 if (n < 3) 828 return size + 1; 829 n -= 3; 830 m = size >> n; 831 m += m == 6 ? 2 : 1; 832 m <<= n; 833 return m > size ? m : (size_t)(-1); 834 } 835 836 /* Read the input file *name, or stdin if name is NULL, into allocated memory. 837 Reallocate to larger buffers until the entire file is read in. Return a 838 pointer to the allocated data, or NULL if there was a memory allocation 839 failure. *len is the number of bytes of data read from the input file (even 840 if load() returns NULL). If the input file was empty or could not be opened 841 or read, *len is zero. */ 842 local void *load(char *name, size_t *len) 843 { 844 size_t size; 845 void *buf, *swap; 796 846 FILE *in; 797 struct stat s;798 847 799 848 *len = 0; 800 if (stat(name, &s)) return NULL; 801 if ((s.st_mode & S_IFMT) != S_IFREG) return NULL; 802 size = (unsigned long)(s.st_size); 803 if (size == 0 || (off_t)size != s.st_size) return NULL; 804 in = fopen(name, "r"); 805 if (in == NULL) return NULL; 806 buf = malloc(size); 807 if (buf != NULL && fread(buf, 1, size, in) != size) { 808 free(buf); 809 buf = NULL; 810 } 811 fclose(in); 812 *len = size; 849 buf = malloc(size = 4096); 850 if (buf == NULL) 851 return NULL; 852 in = name == NULL ? stdin : fopen(name, "rb"); 853 if (in != NULL) { 854 for (;;) { 855 *len += fread((char *)buf + *len, 1, size - *len, in); 856 if (*len < size) break; 857 size = bythirds(size); 858 if (size == *len || (swap = realloc(buf, size)) == NULL) { 859 free(buf); 860 buf = NULL; 861 break; 862 } 863 buf = swap; 864 } 865 fclose(in); 866 } 813 867 return buf; 814 868 } … … 816 870 int main(int argc, char **argv) 817 871 { 818 int ret; 819 unsigned char *source; 820 unsigned long len, sourcelen, destlen; 821 822 if (argc < 2) return 2; 823 source = yank(argv[1], &len); 824 if (source == NULL) return 2; 825 sourcelen = len; 826 ret = puff(NIL, &destlen, source, &sourcelen); 872 int ret, skip = 0, put = 0; 873 char *arg, *name = NULL; 874 unsigned char *source = NULL, *dest; 875 size_t len = 0; 876 unsigned long sourcelen, destlen; 877 878 /* process arguments */ 879 while (arg = *++argv, --argc) 880 if (arg[0] == '-') { 881 if (arg[1] == 'w' && arg[2] == 0) 882 put = 1; 883 else if (arg[1] >= '0' && arg[1] <= '9') 884 skip = atoi(arg + 1); 885 else { 886 fprintf(stderr, "invalid option %s\n", arg); 887 return 3; 888 } 889 } 890 else if (name != NULL) { 891 fprintf(stderr, "only one file name allowed\n"); 892 return 3; 893 } 894 else 895 name = arg; 896 source = load(name, &len); 897 if (source == NULL) { 898 fprintf(stderr, "memory allocation failure\n"); 899 return 4; 900 } 901 if (len == 0) { 902 fprintf(stderr, "could not read %s, or it was empty\n", 903 name == NULL ? "<stdin>" : name); 904 free(source); 905 return 3; 906 } 907 if (skip >= len) { 908 fprintf(stderr, "skip request of %d leaves no input\n", skip); 909 free(source); 910 return 3; 911 } 912 913 /* test inflate data with offset skip */ 914 len -= skip; 915 sourcelen = (unsigned long)len; 916 ret = puff(NIL, &destlen, source + skip, &sourcelen); 827 917 if (ret) 828 printf("puff() failed with return code %d\n", ret);918 fprintf(stderr, "puff() failed with return code %d\n", ret); 829 919 else { 830 printf("puff() succeeded uncompressing %lu bytes\n", destlen); 831 if (sourcelen < len) printf("%lu compressed bytes unused\n", 832 len - sourcelen); 833 } 920 fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen); 921 if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n", 922 len - sourcelen); 923 } 924 925 /* if requested, inflate again and write decompressd data to stdout */ 926 if (put) { 927 dest = malloc(destlen); 928 if (dest == NULL) { 929 fprintf(stderr, "memory allocation failure\n"); 930 free(source); 931 return 4; 932 } 933 puff(dest, &destlen, source + skip, &sourcelen); 934 fwrite(dest, 1, destlen, stdout); 935 free(dest); 936 } 937 938 /* clean up */ 834 939 free(source); 835 940 return ret;
Note: See TracChangeset
for help on using the changeset viewer.