uncompress.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * uncompress.c
  3. *
  4. * (C) Copyright 1999 Linus Torvalds
  5. *
  6. * cramfs interfaces to the uncompression library. There's really just
  7. * three entrypoints:
  8. *
  9. * - cramfs_uncompress_init() - called to initialize the thing.
  10. * - cramfs_uncompress_exit() - tell me when you're done
  11. * - cramfs_uncompress_block() - uncompress a block.
  12. *
  13. * NOTE NOTE NOTE! The uncompression is entirely single-threaded. We
  14. * only have one stream, and we'll initialize it only once even if it
  15. * then is used by multiple filesystems.
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/errno.h>
  19. #include <linux/vmalloc.h>
  20. #include <linux/zlib.h>
  21. #include <linux/cramfs_fs.h>
  22. static z_stream stream;
  23. static int initialized;
  24. /* Returns length of decompressed data. */
  25. int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
  26. {
  27. int err;
  28. stream.next_in = src;
  29. stream.avail_in = srclen;
  30. stream.next_out = dst;
  31. stream.avail_out = dstlen;
  32. err = zlib_inflateReset(&stream);
  33. if (err != Z_OK) {
  34. printk("zlib_inflateReset error %d\n", err);
  35. zlib_inflateEnd(&stream);
  36. zlib_inflateInit(&stream);
  37. }
  38. err = zlib_inflate(&stream, Z_FINISH);
  39. if (err != Z_STREAM_END)
  40. goto err;
  41. return stream.total_out;
  42. err:
  43. printk("Error %d while decompressing!\n", err);
  44. printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
  45. return -EIO;
  46. }
  47. int cramfs_uncompress_init(void)
  48. {
  49. if (!initialized++) {
  50. stream.workspace = vmalloc(zlib_inflate_workspacesize());
  51. if ( !stream.workspace ) {
  52. initialized = 0;
  53. return -ENOMEM;
  54. }
  55. stream.next_in = NULL;
  56. stream.avail_in = 0;
  57. zlib_inflateInit(&stream);
  58. }
  59. return 0;
  60. }
  61. void cramfs_uncompress_exit(void)
  62. {
  63. if (!--initialized) {
  64. zlib_inflateEnd(&stream);
  65. vfree(stream.workspace);
  66. }
  67. }