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

rasterlite_image.c

/* 
/ rasterlite_image.c
/
/ image methods
/
/ version 1.0, 2009 June 1
/
/ 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 <stdlib.h>
#include <string.h>
#include <limits.h>

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

#include "rasterlite_internals.h"

extern rasterliteImagePrt
image_create (int sx, int sy)
{
/*
/ creating a generic RGB image
/ vaguely inspired by GD lib
*/
    int i;
    int i2;
    rasterliteImagePrt img;
    img = malloc (sizeof (rasterliteImage));
    if (!img)
      return NULL;
    img->pixels = NULL;
    img->sx = sx;
    img->sy = sy;
    img->color_space = COLORSPACE_RGB;
    img->pixels = malloc (sizeof (int *) * sy);
    if (!img->pixels)
      {
        free (img);
        return NULL;
      }
    for (i = 0; i < sy; i++)
      {
        img->pixels[i] = (int *) malloc (sizeof (int) * sx);
        if (!img->pixels[i])
          {
            for (i2 = 0; i2 < i; i2++)
                free (img->pixels[i2]);
            free (img->pixels);
            free (img);
            return NULL;
          }
      }
    return img;
}

extern void
image_destroy (rasterliteImagePrt img)
{
/*
/ destroying a generic RGB image
/ vaguely inspired by GD lib
*/
    int i;
    if (img->pixels)
      {
        for (i = 0; (i < img->sy); i++)
            free (img->pixels[i]);
        free (img->pixels);
      }
    free (img);
}

extern void
image_fill (const rasterliteImagePrt img, int color)
{
/* filling the image with given color */
    int x;
    int y;
    if (img->pixels)
      {
        for (y = 0; y < img->sy; y++)
          {
            for (x = 0; x < img->sx; x++)
                img->pixels[y][x] = color;
          }
      }
}

static void
shrink_by (const rasterliteImagePrt dst, const rasterliteImagePrt src)
{
/*
/ this code is widely base upon the original wxWidgets gwxImage wxImage::ShrinkBy(() function
*/
    int xFactor = src->sx / dst->sx;
    int yFactor = src->sy / dst->sy;
    int x;
    int y;
    int x1;
    int y1;
    int y_offset;
    unsigned int avgRed = 0;
    unsigned int avgGreen = 0;
    unsigned int avgBlue = 0;
    unsigned int counter = 0;
    int pixel;
    printf ("shrink\n");
    fflush (stdout);
    for (y = 0; y < dst->sy; y++)
      {
        for (x = 0; x < dst->sx; x++)
          {
            /* determine average */
            for (y1 = 0; y1 < yFactor; ++y1)
              {
                  y_offset = (y * yFactor + y1) * src->sx;
                  for (x1 = 0; x1 < xFactor; ++x1)
                  {
                      pixel = src->pixels[y1][x1];
                      avgRed += true_color_get_red (pixel);
                      avgGreen += true_color_get_green (pixel);
                      avgBlue += true_color_get_blue (pixel);
                      counter++;
                  }
              }
            pixel =
                true_color ((avgRed / counter), (avgGreen / counter),
                        (avgBlue / counter));
            dst->pixels[y][x] = pixel;
          }
      }
}

extern void
image_resize (const rasterliteImagePrt dst, const rasterliteImagePrt src)
{
/*
/ this function builds an ordinary quality resized image, applying pixel replication
/
/ this code is widely base upon the original wxWidgets gwxImage wxImage::Scale(() function
/ wxIMAGE_QUALITY_NORMAL
*/
    int x_delta;
    int y_delta;
    int y;
    int j;
    int x;
    int i;
    if ((src->sx % dst->sx) == 0 && src->sx >= dst->sx
      && (src->sy % dst->sy) == 0 && src->sy >= dst->sy)
      {
        shrink_by (src, dst);
        return;
      }
    x = src->sx;
    y = src->sy;
    x_delta = (x << 16) / dst->sx;
    y_delta = (y << 16) / dst->sy;
    y = 0;
    for (j = 0; j < dst->sy; j++)
      {
        x = 0;
        for (i = 0; i < dst->sx; i++)
          {
            dst->pixels[j][i] = src->pixels[y >> 16][x >> 16];
            x += x_delta;
          }
        y += y_delta;
      }
}

#define floor2(exp) ((long) exp)

extern void
make_thumbnail (const rasterliteImagePrt thumbnail,
            const rasterliteImagePrt image)
{
/*
/ this function builds an high quality thumbnail image, applying pixel interpolation
/
/ this code is widely base upon the original GD gdImageCopyResampled() function
*/
    int x, y;
    double sy1, sy2, sx1, sx2;
    for (y = 0; y < thumbnail->sy; y++)
      {
        sy1 = ((double) y) * (double) image->sy / (double) thumbnail->sy;
        sy2 =
            ((double) (y + 1)) * (double) image->sy / (double) thumbnail->sy;
        for (x = 0; x < thumbnail->sx; x++)
          {
            double sx, sy;
            double spixels = 0;
            double red = 0.0, green = 0.0, blue = 0.0;
            sx1 =
                ((double) x) * (double) image->sx / (double) thumbnail->sx;
            sx2 =
                ((double) (x + 1)) * (double) image->sx /
                (double) thumbnail->sx;
            sy = sy1;
            do
              {
                  double yportion;
                  if (floor2 (sy) == floor2 (sy1))
                  {
                      yportion = 1.0 - (sy - floor2 (sy));
                      if (yportion > sy2 - sy1)
                        {
                          yportion = sy2 - sy1;
                        }
                      sy = floor2 (sy);
                  }
                  else if (sy == floor2 (sy2))
                  {
                      yportion = sy2 - floor2 (sy2);
                  }
                  else
                  {
                      yportion = 1.0;
                  }
                  sx = sx1;
                  do
                  {
                      double xportion;
                      double pcontribution;
                      int p;
                      if (floor2 (sx) == floor2 (sx1))
                        {
                          xportion = 1.0 - (sx - floor2 (sx));
                          if (xportion > sx2 - sx1)
                            {
                              xportion = sx2 - sx1;
                            }
                          sx = floor2 (sx);
                        }
                      else if (sx == floor2 (sx2))
                        {
                          xportion = sx2 - floor2 (sx2);
                        }
                      else
                        {
                          xportion = 1.0;
                        }
                      pcontribution = xportion * yportion;
                      p = image->pixels[(int) sy][(int) sx];
                      red += true_color_get_red (p) * pcontribution;
                      green += true_color_get_green (p) * pcontribution;
                      blue += true_color_get_blue (p) * pcontribution;
                      spixels += xportion * yportion;
                      sx += 1.0;
                  }
                  while (sx < sx2);
                  sy += 1.0;
              }
            while (sy < sy2);
            if (spixels != 0.0)
              {
                  red /= spixels;
                  green /= spixels;
                  blue /= spixels;
              }
            if (red > 255.0)
                red = 255.0;
            if (green > 255.0)
                green = 255.0;
            if (blue > 255.0)
                blue = 255.0;
            image_set_pixel (thumbnail, x, y,
                         true_color ((int) red, (int) green,
                                   (int) blue));
          }
      }
}

extern void *
image_to_rgb_array (const rasterliteImagePrt img, int *size)
{
/* building a flat RGB array from this image */
    int x;
    int y;
    int pixel;
    unsigned char *data = NULL;
    unsigned char *p;
    int sz = img->sx * img->sy * 3;
    *size = 0;
/* allocating the RGB array */
    data = malloc (sz);
    p = data;
    for (y = 0; y < img->sy; y++)
      {
        for (x = 0; x < img->sx; x++)
          {
            pixel = img->pixels[y][x];
            *p++ = true_color_get_red (pixel);
            *p++ = true_color_get_green (pixel);
            *p++ = true_color_get_blue (pixel);
          }
      }
    *size = sz;
    return data;
}

Generated by  Doxygen 1.6.0   Back to index