File:  [Repository ATC2] / QuadraticMandel / mypng.c
Revision 1.2: download - view: text, annotated - select for diffs
Tue Oct 18 09:02:34 2011 UTC (12 years, 6 months ago) by cvsmgr
Branches: MAIN
CVS tags: HEAD
Quadratic fractal set generation.

/*******************************************************************************
+*  Fractal set generation for quadratic maps.
+*  Copyright (C) 2011, Raúl Durán Díaz, raul.duran@uah.es
+*
+*  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/>.
*******************************************************************************/
/*******************************************************************************
+* Soporte para librería png.
+*
+* 7.07.2005
+*
+* $Id: mypng.c,v 1.2 2011/10/18 09:02:34 cvsmgr Exp $
+* $Name:  $
*******************************************************************************/
# include <stdlib.h>
# include <time.h>
# include "mypng.h"

static int    num_rows  = NUM_ROWS;
static int    num_cols  = NUM_COLS;
static double lado      = SIDE;
static double inc       = INCR;
static double offset_x  = 0.0;
static double offset_y  = 0.0;


static png_bytepp AllocateRowPointers(png_uint_32 height, png_uint_32 width)
{
png_bytepp row_pointers = png_bytepp_NULL;
int i;

   row_pointers = (png_bytepp) malloc(height*sizeof(png_bytep));

   if (row_pointers)
      for (i = 0; i < height; i++)
         row_pointers[i] = (png_bytep) malloc(3*width*sizeof(png_byte));

   return row_pointers;
}

static void FreeRowPointers(png_bytepp row_pointers, png_uint_32 height)
{
int i;

   for (i = 0; i < height; i++)
      free(row_pointers[i]);

   free(row_pointers);
}

static void CopyImage(png_colorpp pixels, png_bytepp row_pointers,
                      png_uint_32 height, png_uint_32 width)
{
png_uint_32 i, j;

   for (i = 0; i < height; i++)
   {
      for (j = 0; j < width; j++)
      {
         row_pointers[i][3*j  ] = pixels[i][j].red;     /* RED */
         row_pointers[i][3*j+1] = pixels[i][j].green;   /* GREEN */
         row_pointers[i][3*j+2] = pixels[i][j].blue;    /* BLUE */
      }
   }
}

void BuildTextPtr(png_textp info_text, double alpha, double beta, int itermax,
                  double side_len, double offset_x, double offset_y)
{
int         i;
time_t      hora = time(NULL);
struct tm  *t_hora = localtime(&hora);
static char texts[NUM_TEXT][TEXT_LENGTH];

   for (i = 0; i < NUM_TEXT; i++)
   {
      info_text[i].compression = PNG_TEXT_COMPRESSION_NONE;
      info_text[i].text        = texts[i];
   }

   info_text[0].key         = "Xi";
   info_text[0].text_length = 0;
   sprintf(texts[0], "%lf", alpha);

   info_text[1].key         = "Eta";
   info_text[1].text_length = 0;
   sprintf(texts[1], "%lf", beta);

   info_text[2].key         = "Iterations";
   info_text[2].text_length = 0;
   sprintf(texts[2], "%d", itermax);

   info_text[3].key         = "Side length";
   info_text[3].text_length = 0;
   sprintf(texts[3], "%lf", side_len);

   info_text[4].key         = "Offset x";
   info_text[4].text_length = 0;
   sprintf(texts[4], "%lf", offset_x);

   info_text[5].key         = "Offset y";
   info_text[5].text_length = 0;
   sprintf(texts[5], "%lf", offset_y);

   info_text[6].key         = "Date";
   info_text[6].text_length = 0;
   sprintf(texts[6], "%2d.%02d.%d %2d:%02d", t_hora->tm_mday,
                                             t_hora->tm_mon  + 1,
                                             t_hora->tm_year + 1900,
                                             t_hora->tm_hour,
                                             t_hora->tm_min);
}

void DrawVertiLine(png_colorpp image, double coord_x, png_color p)
{
int x = CoordXToPix(coord_x);
int i;

   for (i = 0; i < num_rows; i++)
   {
      image[i][x].red   = p.red;
      image[i][x].green = p.green;
      image[i][x].blue  = p.blue;
   }
}

void DrawHorizLine(png_colorpp image, double coord_y, png_color p)
{
int y = CoordYToPix(coord_y);
int i;

   for (i = 0; i < num_cols; i++)
   {
      image[y][i].red   = p.red;
      image[y][i].green = p.green;
      image[y][i].blue  = p.blue;
   }
}

int CoordXToPix(double x)
{
int xtemp = (x - offset_x)/inc + 0.5;

   if (xtemp >=  num_cols/2) xtemp =  num_cols/2 - 1;
   if (xtemp <  -num_cols/2) xtemp = -num_cols/2;

   return xtemp + num_cols/2;
}

int CoordYToPix(double y)
{
int ytemp = (offset_y - y)/inc + 0.5;

   if (ytemp >=  num_rows/2) ytemp =  num_rows/2 - 1;
   if (ytemp <  -num_rows/2) ytemp = -num_rows/2;

   return ytemp + num_rows/2;
}

double PixToCoordX(int x)
{
   return (x - num_cols/2)*inc + offset_x;
}

double PixToCoordY(int y)
{
   return (num_rows/2 - y)*inc + offset_y;
}

void SetSide(double l)
{
   lado = l;
   inc = lado/num_cols;
}

void SetOffsetX(double off_x)
{
   offset_x = off_x;
}

void SetOffsetY(double off_y)
{
   offset_y = off_y;
}

void SetImageSize(int rows, int columns)
{
   num_rows = rows;
   num_cols = columns;
   inc      = lado/num_cols;
}

void DeallocatePNG(png_colorpp p, png_uint_32 height, png_uint_32 width)
{
int i = 0;

   if (p)
      for (i = 0; i < height; i++)
         free(p[i]);

   free(p);
}

png_colorpp AllocatePNG(png_uint_32 height, png_uint_32 width)
{
png_colorpp p = (png_colorpp) NULL;
int     i = 0;

   p = (png_colorpp) calloc(height, sizeof(png_colorp));

   if (p)
      for (i = 0; i < height; i++)
         p[i] = (png_colorp) calloc(width, sizeof(png_color));

   SetImageSize(height, width);
   return p;
}

BOOL WritePNG(char *file_name, png_colorpp pixels,
              png_textp text_ptr, int num_text)
{
FILE        *fp;
png_structp  png_ptr;
png_infop    info_ptr;
int          png_transforms = 0;
png_bytepp   row_pointers = AllocateRowPointers(num_rows, num_cols);

   if ((fp = fopen(file_name, "wb")) == NULL)
   {
      FreeRowPointers(row_pointers, num_rows);
      return ERROR;
   }

   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                     png_voidp_NULL,
                                     png_voidp_NULL,
                                     png_voidp_NULL);

   if (png_ptr == NULL)
   {
      fclose(fp);
      FreeRowPointers(row_pointers, num_rows);
      return ERROR;
   }

   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL)
   {
      fclose(fp);
      png_destroy_write_struct(&png_ptr,  png_infopp_NULL);
      FreeRowPointers(row_pointers, num_rows);
      return ERROR;
   }

   if (setjmp(png_jmpbuf(png_ptr)))
   {
      fclose(fp);
      png_destroy_write_struct(&png_ptr, &info_ptr);
      FreeRowPointers(row_pointers, num_rows);
      return ERROR;
   }

   png_init_io(png_ptr, fp);

   png_set_IHDR(png_ptr, info_ptr,
                num_cols,               /* width in pixels */
                num_rows,               /* height in pixels */
                8,                      /* bit depth of one of the */
                                        /* image channels: 1, 2, 4, 8, 16 */
                PNG_COLOR_TYPE_RGB,     /* describes which color/alpha */
                                        /* channels are present */
                PNG_INTERLACE_ADAM7,    /* PNG_INTERLACE_NONE */
                PNG_COMPRESSION_TYPE_DEFAULT,
                PNG_FILTER_TYPE_DEFAULT);


   CopyImage(pixels, row_pointers, num_rows, num_cols);
   png_set_rows(png_ptr, info_ptr, row_pointers);
   png_set_text(png_ptr, info_ptr, text_ptr, num_text);

   png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);

   /* clean up after the write, and free any memory allocated */
   png_destroy_write_struct(&png_ptr, &info_ptr);

   /* close the file */
   fclose(fp);
   FreeRowPointers(row_pointers, num_rows);

   /* that's it */
   return OK;
}

BOOL ReadPNGText(char *file_name)
{
FILE        *fp;
png_structp  png_ptr;
png_infop    info_ptr;
png_textp    text_ptr;
int          num_comments = 0;
int          num_text;
int          i;

   if ((fp = fopen(file_name, "rb")) == NULL)
      return ERROR;

   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                    png_voidp_NULL,
                                    png_voidp_NULL,
                                    png_voidp_NULL);

   if (png_ptr == NULL)
   {
      fclose(fp);
      return ERROR;
   }

   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL)
   {
      fclose(fp);
      png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
      return ERROR;
   }

   if (setjmp(png_jmpbuf(png_ptr)))
   {
      fclose(fp);
      png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
      return ERROR;
   }

   png_init_io(png_ptr, fp);

   do
   {
      png_read_info(png_ptr, info_ptr);
   } while (/* png_get_valid(png_ptr, info_ptr, PNG_INFO_text) < */0);


   num_comments = png_get_text(png_ptr, info_ptr, &text_ptr, &num_text);

   if (num_comments == 0)
      printf("No information available.\n");
   else
   {
      for (i = 0; i < num_comments; i++)
         printf("%-11s: %12s\n", text_ptr[i].key, text_ptr[i].text);
   }

   /* clean up after the write, and free any memory allocated */
   png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);

   /* close the file */
   fclose(fp);

   /* that's it */
   return OK;
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>