Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2.  
  3. #include <zlib.h>
  4.  
  5. typedef struct fz_flate_s fz_flate;
  6.  
  7. struct fz_flate_s
  8. {
  9.         fz_stream *chain;
  10.         z_stream z;
  11. };
  12.  
  13. static void *zalloc(void *opaque, unsigned int items, unsigned int size)
  14. {
  15.         return fz_calloc(items, size);
  16. }
  17.  
  18. static void zfree(void *opaque, void *ptr)
  19. {
  20.         fz_free(ptr);
  21. }
  22.  
  23. static int
  24. read_flated(fz_stream *stm, unsigned char *outbuf, int outlen)
  25. {
  26.         fz_flate *state = stm->state;
  27.         fz_stream *chain = state->chain;
  28.         z_streamp zp = &state->z;
  29.         int code;
  30.  
  31.         zp->next_out = outbuf;
  32.         zp->avail_out = outlen;
  33.  
  34.         while (zp->avail_out > 0)
  35.         {
  36.                 if (chain->rp == chain->wp)
  37.                         fz_fill_buffer(chain);
  38.  
  39.                 zp->next_in = chain->rp;
  40.                 zp->avail_in = chain->wp - chain->rp;
  41.  
  42.                 code = inflate(zp, Z_SYNC_FLUSH);
  43.  
  44.                 chain->rp = chain->wp - zp->avail_in;
  45.  
  46.                 if (code == Z_STREAM_END)
  47.                 {
  48.                         return outlen - zp->avail_out;
  49.                 }
  50.                 else if (code == Z_BUF_ERROR)
  51.                 {
  52.                         fz_warn("premature end of data in flate filter");
  53.                         return outlen - zp->avail_out;
  54.                 }
  55.                 else if (code == Z_DATA_ERROR && zp->avail_in == 0)
  56.                 {
  57.                         fz_warn("ignoring zlib error: %s", zp->msg);
  58.                         return outlen - zp->avail_out;
  59.                 }
  60.                 else if (code != Z_OK)
  61.                 {
  62.                         return fz_throw("zlib error: %s", zp->msg);
  63.                 }
  64.         }
  65.  
  66.         return outlen - zp->avail_out;
  67. }
  68.  
  69. static void
  70. close_flated(fz_stream *stm)
  71. {
  72.         fz_flate *state = stm->state;
  73.         int code;
  74.  
  75.         code = inflateEnd(&state->z);
  76.         if (code != Z_OK)
  77.                 fz_warn("zlib error: inflateEnd: %s", state->z.msg);
  78.  
  79.         fz_close(state->chain);
  80.         fz_free(state);
  81. }
  82.  
  83. fz_stream *
  84. fz_open_flated(fz_stream *chain)
  85. {
  86.         fz_flate *state;
  87.         int code;
  88.  
  89.         state = fz_malloc(sizeof(fz_flate));
  90.         state->chain = chain;
  91.  
  92.         state->z.zalloc = zalloc;
  93.         state->z.zfree = zfree;
  94.         state->z.opaque = NULL;
  95.         state->z.next_in = NULL;
  96.         state->z.avail_in = 0;
  97.  
  98.         code = inflateInit(&state->z);
  99.         if (code != Z_OK)
  100.                 fz_warn("zlib error: inflateInit: %s", state->z.msg);
  101.  
  102.         return fz_new_stream(state, read_flated, close_flated);
  103. }
  104.