Logo Search packages:      
Sourcecode: librasterlite version File versions  Download package

rasterlite_wavelet.c

/* 
/ rasterlite_wavelet.c
/
/ WAVELET auxiliary helpers
/
/ version 1.0, 2009 June 5
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ Copyright (C) 2009  Alessandro Furieri
/
/    This program is free software: you can redistribute it and/or modify
/    it under the terms of the GNU General Public License as published by
/    the Free Software Foundation, either version 3 of the License, or
/    (at your option) any later version.
/
/    This program is distributed in the hope that it will be useful,
/    but WITHOUT ANY WARRANTY; without even the implied warranty of
/    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
/    GNU General Public License for more details.
/
/    You should have received a copy of the GNU General Public License
/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
/
*/

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

#include <epsilon.h>

#include <spatialite/sqlite3.h>
#include <spatialite/gaiageo.h>

#include <tiffio.h>

#include "rasterlite_internals.h"

/* 
/
/ this code is widely based upon the cmd_encode_file.c 
/ source from the 'epsilon' library
/
*/

#define BIORTHOGONAL    1

#define MAX(_x, _y)           ((_x) > (_y) ? (_x) : (_y))

00052 typedef struct decode_ctx_tag
{
    int buf_size;
    int n_blocks;
    int *done_blocks;
    int W;
    int H;
    int max_block_w;
    int max_block_h;
    rasterliteImagePrt img;
    int image_type;
    unsigned char *input;
    int in_size;
    int in_base;
    int in_current;
    int *clear_len;
    int *stop_flag;
} decode_ctx;

00071 typedef struct encode_ctx_tag
{
    char *filter_id;
    int block_size;
    int mode;
    int bytes_per_block;
    double Y_ratio;
    double Cb_ratio;
    double Cr_ratio;
    int resample;
    int W;
    int H;
    rasterliteImagePrt img;
    int image_type;
    unsigned char *output;
    int out_size;
    int out_current;
    int n_blocks;
    int *done_blocks;
    int *clear_len;
    int *stop_flag;
} encode_ctx;

static int
get_byte (decode_ctx * ctx)
{
/* fetching the next byte from the input source */
    if (ctx->in_current < ctx->in_size)
      return *(ctx->input + ctx->in_current++);
    return EOF;
}

static int
decoder_read_next_block (decode_ctx * ctx, unsigned char *buf, int *buf_size)
{
/* inserting input into the input buffer [decompressed image] */
    unsigned char *next_byte;
    int bytes_left;
    int ch;
/* Copy no more than *buf_size bytes */
    bytes_left = *buf_size;
    next_byte = buf;
/* Find first non-marker byte */
    for (;;)
      {
        ch = get_byte (ctx);
        if (ch == EOF)
            return 0;
        if (ch != EPS_MARKER)
          {
            *next_byte++ = (unsigned char) ch;
            bytes_left--;
            break;
          }
      }
/* Copy data until next marker, EOF or buffer end */
    for (;;)
      {
        ch = get_byte (ctx);
        if ((ch == EOF) || (ch == EPS_MARKER))
            break;
/* No more space in the buffer or currupted data. Continue until EOF or syncronization marker */
        if (!bytes_left)
            continue;
        *next_byte++ = (unsigned char) ch;
        bytes_left--;
      }
/* Actual number of read bytes */
    *buf_size = next_byte - buf;
    return 1;
}

static int
guess_wavelet_type (decode_ctx * ctx, int *ext_type, int *width, int *height,
                int *max_block_w, int *max_block_h)
{
/* Block buffer */
    unsigned char *buf;
    int buf_size;
/* Image characteristics */
    int W;
    int H;
    int w;
    int h;
    int type;
/* Allocate block buffer */
    buf_size = MAX (EPS_MAX_GRAYSCALE_BUF, EPS_MAX_TRUECOLOR_BUF);
    buf = (unsigned char *) eps_xmalloc (buf_size);
    W = H = w = h = type = -1;
/* For all blocks */
    while (1)
      {
        eps_block_header hdr;
        /* Read next block */
        if (!decoder_read_next_block (ctx, buf, &buf_size))
            break;
/* Parse block header */
        if (eps_read_block_header (buf, buf_size, &hdr) != EPS_OK)
            continue;
/* Check block header CRC */
        if (hdr.chk_flag == EPS_BAD_CRC)
            continue;
/* Image type */
        if (type == -1)
            type = hdr.block_type;
        else
          {
            if (type != hdr.block_type)
                return 0;
          }
/* Image width */
        if (W == -1)
            W = type == EPS_GRAYSCALE_BLOCK ? hdr.gs.W : hdr.tc.W;
        else
          {
            if (type == EPS_GRAYSCALE_BLOCK ? W != hdr.gs.W : W != hdr.tc.W)
                return 0;
          }
/* Image height */
        if (H == -1)
            H = type == EPS_GRAYSCALE_BLOCK ? hdr.gs.H : hdr.tc.H;
        else
          {
            if (type == EPS_GRAYSCALE_BLOCK ? H != hdr.gs.H : H != hdr.tc.H)
                return 0;
          }
/* Maximal block width and height */
        if (type == EPS_GRAYSCALE_BLOCK)
          {
            if (hdr.gs.w > w)
                w = hdr.gs.w;
            if (hdr.gs.h > h)
                h = hdr.gs.h;
          }
        else
          {
            if (hdr.tc.w > w)
                w = hdr.tc.w;
            if (hdr.tc.h > h)
                h = hdr.tc.h;
          }
      }
/* Rewind file and free buffer */
    ctx->in_current = ctx->in_base;
    free (buf);
/* Buggy file */
    if (type == -1 || W == -1 || H == -1 || w == -1 || h == -1)
      return 0;
/* Save results */
    *ext_type =
      (type == EPS_GRAYSCALE_BLOCK) ? IMAGE_WAVELET_BW : IMAGE_WAVELET_RGB;
    *width = W;
    *height = H;
    *max_block_w = w;
    *max_block_h = h;
    return 1;
}

static int
encoder_read_grayscale (rasterliteImagePrt img, unsigned char **Y, int x,
                  int y, int width, int height)
{
/* fetching GRAYSCALE pixels from the uncompressed image */
    int j;
    int i;
    int pixel;
    int *p_scan;
/* Check params for consistency */
    if (x < 0 || y < 0)
      return 0;
    if (x >= img->sx || y >= img->sy)
      return 0;
    if (width <= 0 || height <= 0)
      return 0;
    if (x + width > img->sx)
      return 0;
    if (y + height > img->sy)
      return 0;
    for (j = 0; j < height; j++)
      {
        /* fetching image rows */
        p_scan = img->pixels[y + j];
        p_scan += x;
        for (i = 0; i < width; i++)
          {
            /* fetching pixel by scanline */
            pixel = *p_scan++;
            Y[j][i] = true_color_get_red (pixel);
          }
      }
    return 1;
}

static int
encoder_read_rgb (rasterliteImagePrt img, unsigned char **R, unsigned char **G,
              unsigned char **B, int x, int y, int width, int height)
{
/* fetching RGB pixels from the uncompressed image */
    int j;
    int i;
    int pixel;
    int *p_scan;
/* Check params for consistency */
    if (x < 0 || y < 0)
      return 0;
    if (x >= img->sx || y >= img->sy)
      return 0;
    if (width <= 0 || height <= 0)
      return 0;
    if (x + width > img->sx)
      return 0;
    if (y + height > img->sy)
      return 0;
    for (j = 0; j < height; j++)
      {
        /* fetching image rows */
        p_scan = img->pixels[y + j];
        p_scan += x;
        for (i = 0; i < width; i++)
          {
            /* fetching pixel by scanline */
            pixel = *p_scan++;
            R[j][i] = true_color_get_red (pixel);
            G[j][i] = true_color_get_green (pixel);
            B[j][i] = true_color_get_blue (pixel);
          }
      }
    return 1;
}

static int
decoder_write_grayscale (rasterliteImagePrt img, unsigned char **Y, int x,
                   int y, int width, int height)
{
/* feeding grayscale pixels into the uncompressed image */
    int i;
    int j;
    int gray;
    int *p_scan;
/* Check params for consistency */
    if ((x < 0) || (y < 0))
      return 0;
    if (x >= img->sx || y >= img->sy)
      return 0;
    if (width <= 0 || height <= 0)
      return 0;
    if (x + width > img->sx)
      return 0;
    if (y + height > img->sy)
      return 0;
    for (j = 0; j < height; j++)
      {
        p_scan = img->pixels[y + j];
        p_scan += x;
        for (i = 0; i < width; i++)
          {
            gray = Y[j][i];
            *p_scan++ = true_color (gray, gray, gray);
          }
      }
    return 1;
}

static int
decoder_write_rgb (rasterliteImagePrt img, unsigned char **R,
               unsigned char **G, unsigned char **B, int x, int y,
               int width, int height)
{
/* feeding RGB pixels into the uncompressed image */
    int i;
    int j;
    int red;
    int green;
    int blue;
    int *p_scan;
/* Check params for consistency */
    if ((x < 0) || (y < 0))
      return 0;
    if (x >= img->sx || y >= img->sy)
      return 0;
    if (width <= 0 || height <= 0)
      return 0;
    if (x + width > img->sx)
      return 0;
    if (y + height > img->sy)
      return 0;
    for (j = 0; j < height; j++)
      {
        p_scan = img->pixels[y + j];
        p_scan += x;
        for (i = 0; i < width; i++)
          {
            red = R[j][i];
            green = G[j][i];
            blue = B[j][i];
            *p_scan++ = true_color (red, green, blue);
          }
      }
    return 1;
}

static int
encoder_write_next_block (encode_ctx * ctx, unsigned char *buf, int buf_size)
{
/* inserting output into the output buffer [compressed image] */
    if (ctx->out_current + buf_size + 1 > ctx->out_size)
      return 0;
/* Write data */
    memcpy (ctx->output + ctx->out_current, buf, buf_size);
    ctx->out_current += buf_size;
/* Write syncronization marker */
    *(ctx->output + ctx->out_current) = EPS_MARKER;
    ctx->out_current++;
    return 1;
}

static int
encode_blocks (encode_ctx * ctx)
{
/* Input buffers */
    unsigned char **Y;
    unsigned char **R;
    unsigned char **G;
    unsigned char **B;
/* Output buffer */
    unsigned char *buf;
    int buf_size;
    int x;
    int y;
    int w;
    int h;
    char header[128];
/* Handy shortcuts */
    int block_size = ctx->block_size;
    int W = ctx->W;
    int H = ctx->H;
/* Error flag */
    int error_flag = 0;
/* Write wavelet image header */
    strcpy (header, "StartWaveletsImage$$");
    if (!encoder_write_next_block
      (ctx, (unsigned char *) header, strlen (header)))
      {
        error_flag = 1;
        fprintf (stderr, "Waveletets-wrapper: Cannot write header\n");
        goto error;
      }
/* Allocate input buffers */
    if (ctx->image_type == IMAGE_WAVELET_BW)
      Y = (unsigned char **) eps_malloc_2D (block_size, block_size,
                                    sizeof (unsigned char));
    else
      {
        R = (unsigned char **) eps_malloc_2D (block_size, block_size,
                                    sizeof (unsigned char));
        G = (unsigned char **) eps_malloc_2D (block_size, block_size,
                                    sizeof (unsigned char));
        B = (unsigned char **) eps_malloc_2D (block_size, block_size,
                                    sizeof (unsigned char));
      }
/* Allocate output buffer */
    buf = (unsigned char *) eps_xmalloc (ctx->bytes_per_block);
/* Process all blocks */
    for (y = 0; y < H; y += block_size)
      {
        for (x = 0; x < W; x += block_size)
          {
            /* Block width */
            if (x + block_size > W)
                w = W - x;
            else
                w = block_size;
            /* Block height */
            if (y + block_size > H)
                h = H - y;
            else
                h = block_size;
            /* Output buffer size (not including marker) */
            buf_size = ctx->bytes_per_block - 1;
            if (ctx->image_type == IMAGE_WAVELET_BW)
              {
                  /* Read next block */
                  if (!encoder_read_grayscale (ctx->img, Y, x, y, w, h))
                  {
                      error_flag = 1;
                      fprintf (stderr,
                             "Waveletets-wrapper: Cannot read block\n");
                      goto error;
                  }
                  /* Encode block */
                  if (eps_encode_grayscale_block
                    (Y, W, H, w, h, x, y, buf, &buf_size, ctx->filter_id,
                     ctx->mode) != EPS_OK)
                  {
                      /* All function parameters are checked at the moment,  so everything except EPS_OK is a logical error. */
                      error_flag = 1;
                      fprintf (stderr,
                             "Waveletets-wrapper: encoder error\n");
                      goto error;
                  }
                  /* Write encoded block */
                  if (!encoder_write_next_block (ctx, buf, buf_size))
                  {
                      error_flag = 1;
                      fprintf (stderr,
                             "Waveletets-wrapper: Cannot write block\n");
                      goto error;
                  }
              }
            else
              {
                  /* Read next block */
                  if (!encoder_read_rgb (ctx->img, R, G, B, x, y, w, h))
                  {
                      error_flag = 1;
                      fprintf (stderr,
                             "Waveletets-wrapper: Cannot read block\n");
                      goto error;
                  }
                  /* Encode block */
                  if (eps_encode_truecolor_block
                    (R, G, B, W, H, w, h, x, y, ctx->resample, buf,
                     &buf_size, ctx->Y_ratio, ctx->Cb_ratio,
                     ctx->Cr_ratio, ctx->filter_id, ctx->mode) != EPS_OK)
                  {
                      /* All function parameters are checked at the moment,  so everything except EPS_OK is a logical error. */
                      error_flag = 1;
                      fprintf (stderr,
                             "Waveletets-wrapper: encoder error\n");
                      goto error;
                  }
                  /* Write encoded block */
                  if (!encoder_write_next_block (ctx, buf, buf_size))
                  {
                      error_flag = 1;
                      fprintf (stderr,
                             "Waveletets-wrapper: Cannot write block\n");
                      goto error;
                  }
              }
          }
      }
/* Write wavelet image footer */
    strcpy (header, "$$EndWaveletsImage");
    if (!encoder_write_next_block
      (ctx, (unsigned char *) header, strlen (header)))
      {
        error_flag = 1;
        fprintf (stderr, "Waveletets-wrapper: Cannot write footer\n");
        goto error;
      }
  error:
/* Free input buffers */
    if (ctx->image_type == IMAGE_WAVELET_BW)
      eps_free_2D ((void **) Y, block_size, block_size);
    else
      {
        eps_free_2D ((void **) R, block_size, block_size);
        eps_free_2D ((void **) G, block_size, block_size);
        eps_free_2D ((void **) B, block_size, block_size);
      }
/* Free output buffer */
    free (buf);
/* Return 0 for success or 1 for error */
    return error_flag;
}

static void *
wavelet_compress (rasterliteImagePrt img, int *size, int ratio, int image_type)
{
/* preparing the compression */
    int W;
    int H;
    int bytes_per_block;
    int x_blocks;
    int y_blocks;
    int n_blocks;
    int block_size = 257;
    int data_size;
    int done_blocks = 0;
    int clear_len = 0;
    int stop_flag = 0;
    encode_ctx ctx;
    int ret;
/* Get image width and height */
    W = img->sx;
    H = img->sy;
    data_size = img->sx * img->sy;
    if (image_type != IMAGE_WAVELET_BW)
      data_size *= 3;
/* Compute number of blocks */
    if (W % block_size)
      x_blocks = W / block_size + 1;
    else
      x_blocks = W / block_size;
    if (H % block_size)
      y_blocks = H / block_size + 1;
    else
      y_blocks = H / block_size;
/* Compute number of bytes per block */
    n_blocks = x_blocks * y_blocks;
    bytes_per_block = (int) ((double) data_size / (ratio * n_blocks));
/* Clip buffer size if needed */
    if (image_type == IMAGE_WAVELET_BW)
      bytes_per_block = MAX (bytes_per_block, EPS_MIN_GRAYSCALE_BUF + 1);
    else
      bytes_per_block = MAX (bytes_per_block, EPS_MIN_TRUECOLOR_BUF + 1);
    /* Prepare CTXs */
    ctx.filter_id = malloc (strlen ("daub97lift") + 1);
    strcpy (ctx.filter_id, "daub97lift");
    ctx.block_size = block_size;
    ctx.mode = EPS_MODE_OTLPF;
    ctx.bytes_per_block = bytes_per_block;
    ctx.Y_ratio = EPS_Y_RT;
    ctx.Cb_ratio = EPS_Cb_RT;
    ctx.Cr_ratio = EPS_Cr_RT;
    ctx.resample = EPS_RESAMPLE_420;
    ctx.W = W;
    ctx.H = H;
    ctx.img = img;
    ctx.image_type = image_type;
    ctx.output = malloc (1024 * 1024);
    ctx.out_size = 1024 * 1024;
    ctx.out_current = 0;
    ctx.n_blocks = n_blocks;
    ctx.done_blocks = &done_blocks;
    ctx.clear_len = &clear_len;
    ctx.stop_flag = &stop_flag;
/* performing actual encoding */
    ret = encode_blocks (&ctx);
/* memory clean-up */
    free (ctx.filter_id);
    if (ret)
      {
        /* error case */
        free (ctx.output);
        *size = 0;
        return NULL;
      }
    *size = ctx.out_current;
    return ctx.output;
}

static int
decode_blocks (decode_ctx * ctx)
{
/* Input buffer */
    unsigned char *buf;
/* Output buffers */
    unsigned char **Y;
    unsigned char **R;
    unsigned char **G;
    unsigned char **B;
/* Handy shortcuts */
    int max_block_w = ctx->max_block_w;
    int max_block_h = ctx->max_block_h;
    int W = ctx->W;
    int H = ctx->H;
/* Error flag */
    int error_flag = 0;
/* Allocate input buffer */
    buf = (unsigned char *) eps_xmalloc (ctx->buf_size);
/* Allocate output buffers */
    if (ctx->image_type == IMAGE_WAVELET_BW)
      Y = (unsigned char **) eps_malloc_2D (max_block_w, max_block_h,
                                    sizeof (unsigned char));
    else
      {
        R = (unsigned char **) eps_malloc_2D (max_block_w, max_block_h,
                                    sizeof (unsigned char));
        G = (unsigned char **) eps_malloc_2D (max_block_w, max_block_h,
                                    sizeof (unsigned char));
        B = (unsigned char **) eps_malloc_2D (max_block_w, max_block_h,
                                    sizeof (unsigned char));
      }
/* Process blocks */
    while (1)
      {
        eps_block_header hdr;
        int real_buf_size = ctx->buf_size;
        int rc;
        /* Are there any unprocessed blocks? */
        if (*ctx->done_blocks == ctx->n_blocks)
            break;
        else
            (*ctx->done_blocks)++;
        /* Read next input block */
        if (!decoder_read_next_block (ctx, buf, &real_buf_size))
          {
            error_flag = 1;
            fprintf (stderr, "Waveletets-wrapper: Cannot read block\n");
            goto error;
          }
        /* Parse and check block header */
        rc = eps_read_block_header (buf, real_buf_size, &hdr);
        if (rc != EPS_OK)
          {
            error_flag = 1;
            fprintf (stderr, "Waveletets-wrapper: Malformed block\n");
            goto error;
          }
        /* Check header CRC flag */
        if (hdr.chk_flag == EPS_BAD_CRC)
          {
            error_flag = 1;
            fprintf (stderr, "Wavelet-wrapper: Incorrect header CRC\n");
            goto error;
          }
        /* Check data CRC flag */
        if (hdr.crc_flag == EPS_BAD_CRC)
          {
            error_flag = 1;
            fprintf (stderr, "Wavelet-wrapper: Incorrect data CRC\n");
            goto error;
          }
        if (ctx->image_type == IMAGE_WAVELET_BW)
          {
            /* Skip over broken blocks */
            if ((hdr.gs.W != W) || (hdr.gs.H != H))
                continue;
            /* All function parameters are checked at the moment so everything except EPS_OK is a logical error. */
            rc = eps_decode_grayscale_block (Y, buf, &hdr);
            if (rc != EPS_OK)
              {
                  error_flag = 1;
                  fprintf (stderr, "Wavelet-wrapper: decode error\n");
                  goto error;
              }
            if (!decoder_write_grayscale
                (ctx->img, Y, hdr.gs.x, hdr.gs.y, hdr.gs.w, hdr.gs.h))
              {
                  error_flag = 1;
                  fprintf (stderr, "Wavelet-wrapper: cannot write block\n");
                  goto error;
              }
          }
        else
          {
            /* Skip over broken blocks */
            if ((hdr.tc.W != W) || (hdr.tc.H != H))
                continue;
            /* Decode block */
            rc = eps_decode_truecolor_block (R, G, B, buf, &hdr);
            if (rc != EPS_OK)
              {
                  error_flag = 1;
                  fprintf (stderr, "Wavelet-wrapper: decode error\n");
                  goto error;
              }
            /* Write encoded block */
            if (!decoder_write_rgb
                (ctx->img, R, G, B, hdr.tc.x, hdr.tc.y, hdr.tc.w, hdr.tc.h))
              {
                  error_flag = 1;
                  fprintf (stderr, "Wavelet-wrapper: cannot write block\n");
                  goto error;
              }
          }
      }
  error:
/* Free input buffer */
    free (buf);
/* Free output buffers */
    if (ctx->image_type == IMAGE_WAVELET_BW)
      eps_free_2D ((void **) Y, max_block_w, max_block_h);
    else
      {
        eps_free_2D ((void **) R, max_block_w, max_block_h);
        eps_free_2D ((void **) G, max_block_w, max_block_h);
        eps_free_2D ((void **) B, max_block_w, max_block_h);
      }
/* Return 0 for success or 1 for error */
    return error_flag;
}

static int
check_header (const void *data, int size)
{
/* checking the SpatiaLite header */
    int len;
    char to_check[64];
    strcpy (to_check, "StartWaveletsImage$$");
    len = strlen (to_check) + 1;
    if (size > len)
      {
        if (memcmp ((char *) data, to_check, len) == 0)
            return len;
      }
    return 0;
}

static int
check_footer (const void *data, int size)
{
/* checking the SpatiaLite footer */
    int len;
    char to_check[64];
    strcpy (to_check, "$$EndWaveletsImage");
    len = strlen (to_check) + 1;
    if (size > len)
      {
        if (memcmp ((char *) data + (size - len), to_check, len) == 0)
            return len;
      }
    return 0;
}

static rasterliteImagePrt
wavelet_uncompress (int size, const void *data)
{
/* preparing the decompression */
    rasterliteImagePrt img;
    int ret;
    decode_ctx ctx;
/* Input buffer size */
    int buf_size;
/* Miscellaneous block stuff */
    int max_block_w;
    int max_block_h;
    int x_blocks;
    int y_blocks;
    int n_blocks;
    int done_blocks = 0;
    int clear_len = 0;
    int stop_flag = 0;
    int W;
    int H;
    int ext_type;
    int len;
/* checking the SpatiaLite header and footer */
    ctx.input = (unsigned char *) data;
    ctx.in_size = size;
    ctx.in_current = 0;
    len = check_header (data, size);
    if (len)
      ctx.in_current += len;
    else
      return NULL;
    len = check_footer (data, size);
    if (len)
      ctx.in_size -= len;
    else
      return NULL;
    ctx.in_base = ctx.in_current;
    if (!guess_wavelet_type
      (&ctx, &ext_type, &W, &H, &max_block_w, &max_block_h))
      return NULL;
    img = image_create (W, H);
/* Compute number of blocks */
    if (W % max_block_w)
      x_blocks = W / max_block_w + 1;
    else
      x_blocks = W / max_block_w;
    if (H % max_block_h)
      y_blocks = H / max_block_h + 1;
    else
      y_blocks = H / max_block_h;
/* Compute total number of blocks in the file */
    n_blocks = x_blocks * y_blocks;
    stop_flag = 0;
/* Prepare CTXs */
    if (ext_type == IMAGE_WAVELET_RGB)
      {
        img->color_space = COLORSPACE_RGB;
        buf_size = EPS_MAX_GRAYSCALE_BUF;
      }
    else
      {
        img->color_space = COLORSPACE_GRAYSCALE;
        buf_size = EPS_MAX_TRUECOLOR_BUF;
      }
    ctx.buf_size = buf_size;
    ctx.n_blocks = n_blocks;
    ctx.done_blocks = &done_blocks;
    ctx.clear_len = &clear_len;
    ctx.W = W;
    ctx.H = H;
    ctx.img = img;
    ctx.max_block_w = max_block_w;
    ctx.max_block_h = max_block_h;
    ctx.stop_flag = &stop_flag;
/* Decode blocks */
    ret = decode_blocks (&ctx);
    if (ret == 0)
      return img;
    image_destroy (img);
    return NULL;
}

extern void *
image_to_wavelet (const rasterliteImagePrt img, int *size, int ratio)
{
/* compressing an image as WAVELET RGB */
    return wavelet_compress (img, size, ratio, IMAGE_WAVELET_RGB);
}

extern void *
image_to_wavelet_grayscale (const rasterliteImagePrt img, int *size, int ratio)
{
/* compressing an image as JPEG WAVELET GRAYSCALE */
    return wavelet_compress (img, size, ratio, IMAGE_WAVELET_BW);
}

extern rasterliteImagePrt
image_from_wavelet (int size, const void *data)
{
/* uncompressing a WAVELET compressed image */
    rasterliteImagePrt img;
    img = wavelet_uncompress (size, data);
    return img;
}

Generated by  Doxygen 1.6.0   Back to index