polaroid-pp

Schlieren and contour plot tool
git clone https://git.0xfab.ch/polaroid-pp.git
Log | Files | Refs | Submodules | README | LICENSE

pngwriter.h (38408B)


      1 //**********  pngwriter.h   **********************************************
      2 //  Author:                    Paul Blackburn
      3 //
      4 //  Email:                     individual61@users.sourceforge.net
      5 //
      6 //  Version:                   0.5.4   (19 / II / 2009)
      7 //
      8 //  Description:               Library that allows plotting a 48 bit
      9 //                             PNG image pixel by pixel, which can
     10 //                             then be opened with a graphics program.
     11 //
     12 //  License:                   GNU General Public License
     13 //                             Copyright 2002, 2003, 2004, 2005, 2006, 2007,
     14 //                             2008, 2009 Paul Blackburn
     15 //
     16 //  Website: Main:             http://pngwriter.sourceforge.net/
     17 //           Sourceforge.net:  http://sourceforge.net/projects/pngwriter/
     18 //           Freshmeat.net:    http://freshmeat.net/projects/pngwriter/
     19 //
     20 //  Documentation:             This header file is commented, but for a
     21 //                             quick reference document, and support,
     22 //                             take a look at the website.
     23 //
     24 //*************************************************************************
     25 
     26 
     27 /*
     28  *     This program is free software; you can redistribute it and/or modify
     29  *     it under the terms of the GNU General Public License as published by
     30  *     the Free Software Foundation; either version 2 of the License, or
     31  *     (at your option) any later version.
     32  *
     33  *     This program is distributed in the hope that it will be useful,
     34  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
     35  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     36  *     GNU General Public License for more details.
     37  *
     38  *     You should have received a copy of the GNU General Public License
     39  *     along with this program; if not, write to the Free Software
     40  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     41  *
     42  * */
     43 
     44 #ifndef PNGWRITER_H
     45 #define PNGWRITER_H 1
     46 
     47 #define PNGWRITER_VERSION 0.54
     48 
     49 #include "png.h"
     50 
     51 // REMEMBER TO ADD -DNO_FREETYPE TO YOUR COMPILATION FLAGS IF PNGwriter WAS
     52 // COMPILED WITHOUT FREETYPE SUPPORT!!!
     53 //
     54 // RECUERDA AGREGAR -DNO_FREETYPE A TUS OPCIONES DE COMPILACION SI PNGwriter
     55 // FUE COMPILADO SIN SOPORTE PARA FREETYPE!!!
     56 //
     57 #define NO_FREETYPE
     58 #ifndef NO_FREETYPE
     59 #include <ft2build.h>
     60 #include FT_FREETYPE_H
     61 #endif
     62 
     63 
     64 
     65 #ifdef OLD_CPP // For compatibility with older compilers.
     66 #include <iostream.h>
     67 #include <math.h>
     68 #include <wchar.h>
     69 #include <string.h>
     70 using namespace std;
     71 #endif // from ifdef OLD_CPP
     72 
     73 #ifndef OLD_CPP // Default situation.
     74 #include <iostream>
     75 #include <cmath>
     76 #include <cwchar>
     77 #include <string>
     78 #endif // from ifndef OLD_CPP
     79 
     80 
     81 //png.h must be included before FreeType headers.
     82 #include <stdlib.h>
     83 #include <stdio.h>
     84 #include <setjmp.h>
     85 
     86 
     87 
     88 
     89 #define PNG_BYTES_TO_CHECK (4)
     90 #define PNGWRITER_DEFAULT_COMPRESSION (6)
     91 
     92 class pngwriter
     93 {
     94  private:
     95 
     96    char * filename_;
     97    char * textauthor_;
     98    char * textdescription_;
     99    char * texttitle_;
    100    char * textsoftware_;
    101 
    102 
    103 
    104    int height_;
    105    int width_;
    106    int  backgroundcolour_;
    107    int bit_depth_;
    108    int rowbytes_;
    109    int colortype_;
    110    int compressionlevel_;
    111    bool transformation_; // Required by Mikkel's patch
    112 
    113    unsigned char * * graph_;
    114    double filegamma_;
    115    double screengamma_;
    116    void circle_aux(int xcentre, int ycentre, int x, int y, int red, int green, int blue);
    117    void circle_aux_blend(int xcentre, int ycentre, int x, int y, double opacity, int red, int green, int blue);
    118    int check_if_png(char *file_name, FILE **fp);
    119    int read_png_info(FILE *fp, png_structp *png_ptr, png_infop *info_ptr);
    120    int read_png_image(FILE *fp, png_structp png_ptr, png_infop info_ptr,
    121  		       png_bytepp *image, png_uint_32 *width, png_uint_32 *height);
    122    void flood_fill_internal( int xstart, int ystart,  double start_red, double start_green, double start_blue, double fill_red, double fill_green, double fill_blue);
    123    void flood_fill_internal_blend( int xstart, int ystart, double opacity,  double start_red, double start_green, double start_blue, double fill_red, double fill_green, double fill_blue);
    124 
    125 #ifndef NO_FREETYPE
    126    void my_draw_bitmap( FT_Bitmap * bitmap, int x, int y, double red, double green, double blue);
    127    void my_draw_bitmap_blend( FT_Bitmap * bitmap, int x, int y,double opacity,  double red, double green, double blue);
    128 #endif
    129 
    130    /* The algorithms HSVtoRGB and RGBtoHSV were found at http://www.cs.rit.edu/~ncs/
    131     * which is a page that belongs to Nan C. Schaller, though
    132     * these algorithms appear to be the work of Eugene Vishnevsky.
    133     * */
    134    void HSVtoRGB( double *r, double *g, double *b, double h, double s, double v );
    135    void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v );
    136 
    137    /* drwatop(), drawbottom() and filledtriangle() were contributed by Gurkan Sengun
    138     * ( <gurkan@linuks.mine.nu>, http://www.linuks.mine.nu/ )
    139     * */
    140    void drawtop(long x1,long y1,long x2,long y2,long x3, int red, int green, int blue);
    141    void drawbottom(long x1,long y1,long x2,long x3,long y3, int red, int green, int blue);
    142    void drawbottom_blend(long x1,long y1,long x2,long x3,long y3, double opacity, int red, int green, int blue);
    143    void drawtop_blend(long x1,long y1,long x2,long y2,long x3, double opacity, int red, int green, int blue);
    144 
    145  public:
    146 
    147    /* General Notes
    148     * It is important to remember that all functions that accept an argument of type "const char *" will also
    149     * accept "char *", this is done so you can have a changing filename (to make many PNG images in series
    150     * with a different name, for example), and to allow you to use string type objects which can be easily
    151     * turned into const char * (if theString is an object of type string, then it can be used as a const char *
    152     * by saying theString.c_str()).
    153     * It is also important to remember that whenever a function has a colour coeffiecient as its argument,
    154     * that argument can be either an int from 0 to 65535 or a double from 0.0 to 1.0.
    155     * It is important to make sure that you are calling the function with the type that you want.
    156     * Remember that 1 is an int, while 1.0 is a double, and will thus determine what version of the function
    157     * will be used. Similarly, do not make the mistake of calling for example plot(x, y, 0.0, 0.0, 65535),
    158     * because
    159     * there is no plot(int, int, double, double, int).
    160     * Also, please note that plot() and read() (and the functions that use them internally)
    161     * are protected against entering, for example, a colour coefficient that is over 65535
    162     * or over 1.0. Similarly, they are protected against negative coefficients. read() will return 0
    163     * when called outside the image range. This is actually useful as zero-padding should you need it.
    164     * */
    165 
    166    /* Compilation
    167     * A typical compilation would look like this:
    168     *
    169     * g++ my_program.cc -o my_program freetype-config --cflags \
    170     *          -I/usr/local/include  -L/usr/local/lib -lpng -lpngwriter -lz -lfreetype
    171     *
    172     * If you did not compile PNGwriter with FreeType support, then remove the
    173     * FreeType-related flags and add -DNO_FREETYPE above.
    174     * */
    175 
    176    /* Constructor
    177     * The constructor requires the width and the height of the image, the background colour for the
    178     * image and the filename of the file (a pointer or simple "myfile.png"). The background colour
    179     * can only be initialized to a shade of grey (once the object has been created you can do whatever
    180     * you want, though), because generally one wants either a white (65535 or 1.0) or a black (0 or 0.0)
    181     * background to start with.
    182     * The default constructor creates a PNGwriter instance that is 250x250, white background,
    183     * and filename "out.png".
    184     * Tip: The filename can be given as easily as:
    185     * pngwriter mypng(300, 300, 0.0, "myfile.png");
    186     * Tip: If you are going to create a PNGwriter instance for reading in a file that already exists,
    187     * then width and height can be 1 pixel, and the size will be automatically adjusted once you use
    188     * readfromfile().
    189     * */
    190    pngwriter();
    191    pngwriter(const pngwriter &rhs);
    192    pngwriter(int width, int height, int backgroundcolour, char * filename);
    193    pngwriter(int width, int height, double backgroundcolour, char * filename);
    194    pngwriter(int width, int height, int backgroundcolour, const char * filename);
    195    pngwriter(int width, int height, double backgroundcolour, const char * filename);
    196 
    197    /* Destructor
    198     * */
    199    ~pngwriter();
    200 
    201    /* Assignment Operator
    202     * */
    203    pngwriter & operator = (const pngwriter & rhs);
    204 
    205    /*  Plot
    206     * With this function a pixel at coordinates (x, y) can be set to the desired colour.
    207     * The pixels are numbered starting from (1, 1) and go to (width, height).
    208     * As with most functions in PNGwriter, it has been overloaded to accept either int arguments
    209     * for the colour coefficients, or those of type double. If they are of type int,
    210     * they go from 0 to 65535. If they are of type double, they go from 0.0 to 1.0.
    211     * Tip: To plot using red, then specify plot(x, y, 1.0, 0.0, 0.0). To make pink,
    212     * just add a constant value to all three coefficients, like this:
    213     * plot(x, y, 1.0, 0.4, 0.4).
    214     * Tip: If nothing is being plotted to your PNG file, make sure that you remember
    215     * to close() the instance before your program is finished, and that the x and y position
    216     * is actually within the bounds of your image. If either is not, then PNGwriter will
    217     * not complain-- it is up to you to check for this!
    218     * Tip: If you try to plot with a colour coefficient out of range, a maximum or minimum
    219     * coefficient will be assumed, according to the given coefficient. For example, attempting
    220     * to plot plot(x, y, 1.0,-0.2,3.7) will set the green coefficient to 0 and the red coefficient
    221     * to 1.0.
    222     * */
    223    void  plot(int x, int y, int red, int green, int blue);
    224    void  plot(int x, int y, double red, double green, double blue);
    225 
    226    /* Plot HSV
    227     * With this function a pixel at coordinates (x, y) can be set to the desired colour,
    228     * but with the colour coefficients given in the Hue, Saturation, Value colourspace.
    229     * This has the advantage that one can determine the colour that will be plotted with
    230     * only one parameter, the Hue. The colour coefficients must go from 0 to 65535 and
    231     * be of type int, or be of type double and go from 0.0 to 1.0.
    232     * */
    233    void plotHSV(int x, int y, double hue, double saturation, double value);
    234    void plotHSV(int x, int y, int hue, int saturation, int value);
    235 
    236    /* Read
    237     * With this function we find out what colour the pixel (x, y) is. If "colour" is 1,
    238     * it will return the red coefficient, if it is set to 2, the green one, and if
    239     * it set to 3, the blue colour coefficient will be returned,
    240     * and this returned value will be of type int and be between 0 and 65535.
    241     * Note that if you call read() on a pixel outside the image range, the value returned
    242     * will be 0.
    243     * */
    244    int read(int x, int y, int colour);
    245 
    246    /* Read, Average
    247     * Same as the above, only that the average of the three colour coefficients is returned.
    248     */
    249    int read(int x, int y);
    250 
    251   /* dRead
    252    * With this function we find out what colour the pixel (x, y) is. If "colour" is 1,
    253    * it will return the red coefficient, if it is set to 2, the green one, and if
    254    * it set to 3, the blue colour coefficient will be returned,
    255    * and this returned value will be of type double and be between 0.0 and 1.0.
    256    * Note that if you call dread() outside the image range, the value returned will be 0.0
    257    * */
    258    double dread(int x, int y, int colour);
    259 
    260    /* dRead, Average
    261     * Same as the above, only that the average of the three colour coefficients is returned.
    262     */
    263    double dread(int x, int y);
    264 
    265    /* Read HSV
    266     * With this function we find out what colour the pixel (x, y) is, but in the Hue,
    267     * Saturation, Value colourspace. If "colour" is 1,
    268     * it will return the Hue coefficient, if it is set to 2, the Saturation one, and if
    269     * it set to 3, the Value colour coefficient will be returned, and this returned
    270     * value will be of type int and be between 0 and 65535. Important: If you attempt
    271     * to read the Hue of a pixel that is a shade of grey, the value returned will be
    272     * nonsensical or even NaN. This is just the way the RGB -> HSV algorithm works:
    273     * the Hue of grey is not defined. You might want to check whether the pixel
    274     * you are reading is grey before attempting a readHSV().
    275     * Tip: This is especially useful for categorizing sections of the image according
    276     * to their colour.
    277     * */
    278    int readHSV(int x, int y, int colour);
    279 
    280   /* dRead HSV
    281    * With this function we find out what colour the pixel (x, y) is, but in the Hue,
    282    * Saturation, Value colourspace. If "colour" is 1,
    283    * it will return the Hue coefficient, if it is set to 2, the Saturation one, and if
    284    * it set to 3, the Value colour coefficient will be returned,
    285    * and this returned value will be of type double and be between 0.0 and 1.0.
    286    * */
    287    double dreadHSV(int x, int y, int colour);
    288 
    289    /* Clear
    290     * The whole image is set to black.
    291     * */
    292    void clear(void);
    293 
    294    /* Close
    295     * Close the instance of the class, and write the image to disk.
    296     * Tip: If you do not call this function before your program ends, no image
    297     * will be written to disk.
    298     * */
    299    void close(void);
    300 
    301    /* Rename
    302     * To rename the file once an instance of pngwriter has been created.
    303     * Useful for assigning names to files based upon their content.
    304     * Tip: This is as easy as calling pngwriter_rename("newname.png")
    305     * If the argument is a long unsigned int, for example 77, the filename will be changed to
    306     * 0000000077.png
    307     * Tip: Use this to create sequences of images for movie generation.
    308     * */
    309    void pngwriter_rename(char * newname);
    310    void pngwriter_rename(const char * newname);
    311    void pngwriter_rename(long unsigned int index);
    312 
    313    /* Figures
    314     * These functions draw basic shapes. Available in both int and double versions.
    315     * The line functions use the fast Bresenham algorithm. Despite the name,
    316     * the square functions draw rectangles. The circle functions use a fast
    317     * integer math algorithm. The filled circle functions make use of sqrt().
    318     * */
    319    void line(int xfrom, int yfrom, int xto, int yto, int red, int green,int  blue);
    320    void line(int xfrom, int yfrom, int xto, int yto, double red, double green,double  blue);
    321 
    322    void triangle(int x1, int y1, int x2, int y2, int x3, int y3, int red, int green, int blue);
    323    void triangle(int x1, int y1, int x2, int y2, int x3, int y3, double red, double green, double blue);
    324 
    325    void square(int xfrom, int yfrom, int xto, int yto, int red, int green,int  blue);
    326    void square(int xfrom, int yfrom, int xto, int yto, double red, double green,double  blue);
    327 
    328    void filledsquare(int xfrom, int yfrom, int xto, int yto, int red, int green,int  blue);
    329    void filledsquare(int xfrom, int yfrom, int xto, int yto, double red, double green,double  blue);
    330 
    331    void circle(int xcentre, int ycentre, int radius, int red, int green, int blue);
    332    void circle(int xcentre, int ycentre, int radius, double red, double green, double blue);
    333 
    334    void filledcircle(int xcentre, int ycentre, int radius, int red, int green, int blue);
    335    void filledcircle(int xcentre, int ycentre, int radius, double red, double green, double blue);
    336 
    337 
    338    /* Read From File
    339     * Open the existing PNG image, and copy it into this instance of the class. It is important to mention
    340     * that PNG variants are supported. Very generally speaking, most PNG files can now be read (as of version 0.5.4),
    341     * but if they have an alpha channel it will be completely stripped. If the PNG file uses GIF-style transparency
    342     * (where one colour is chosen to be transparent), PNGwriter will not read the image properly, but will not
    343     * complain. Also, if any ancillary chunks are included in the PNG file (chroma, filter, etc.), it will render
    344     * with a slightly different tonality. For the vast majority of PNGs, this should not be an issue. Note:
    345     * If you read an 8-bit PNG, the internal representation of that instance of PNGwriter will be 8-bit (PNG
    346     * files of less than 8 bits will be upscaled to 8 bits). To convert it to 16-bit, just loop over all pixels,
    347     * reading them into a new instance of PNGwriter. New instances of PNGwriter are 16-bit by default.
    348     * */
    349 
    350    void readfromfile(char * name);
    351    void readfromfile(const char * name);
    352 
    353    /* Get Height
    354     * When you open a PNG with readfromfile() you can find out its height with this function.
    355     * */
    356    int getheight(void);
    357 
    358    /* Get Width
    359     * When you open a PNG with readfromfile() you can find out its width with this function.
    360     * */
    361    int getwidth(void);
    362 
    363    /* Set Compression Level
    364     * Set the compression level that will be used for the image. -1 is to use the  default,
    365     * 0 is none, 9 is best compression.
    366     * Remember that this will affect how long it will take to close() the image. A value of 2 or 3
    367     * is good enough for regular use, but for storage or transmission you might want to take the time
    368     * to set it at 9.
    369     * */
    370     void setcompressionlevel(int level);
    371 
    372    /* Get Bit Depth
    373     * When you open a PNG with readfromfile() you can find out its bit depth with this function.
    374     * Mostly for troubleshooting uses.
    375     * */
    376    int getbitdepth(void);
    377 
    378    /* Get Colour Type
    379     * When you open a PNG with readfromfile() you can find out its colour type (libpng categorizes
    380     * different styles of image data with this number).
    381     * Mostly for troubleshooting uses.
    382     * */
    383    int getcolortype(void);
    384 
    385    /* Set Gamma Coeff
    386     * Set the image's gamma (file gamma) coefficient. This is experimental, but use it if your image's colours seem too bright
    387     * or too dark. The default value of 0.5 should be fine. The standard disclaimer about Mac and PC gamma
    388     * settings applies.
    389     * */
    390    void setgamma(double gamma);
    391 
    392 
    393    /* Get Gamma Coeff
    394     * Get the image's gamma coefficient. This is experimental.
    395     * */
    396    double getgamma(void);
    397 
    398    /* Bezier Curve
    399     * (After Frenchman Pierre Bˇzier from Regie Renault)
    400     * A collection of formulae for describing curved lines
    401     * and surfaces, first used in 1972 to model automobile surfaces.
    402     *             (from the The Free On-line Dictionary of Computing)
    403     * See http://www.moshplant.com/direct-or/bezier/ for one of many
    404     * available descriptions of bezier curves.
    405     * There are four points used to define the curve: the two endpoints
    406     * of the curve are called the anchor points, while the other points,
    407     * which define the actual curvature, are called handles or control points.
    408     * Moving the handles lets you modify the shape of the curve.
    409     * */
    410 
    411    void bezier(  int startPtX, int startPtY,
    412               int startControlX, int startControlY,
    413               int endPtX, int endPtY,
    414               int endControlX, int endControlY,
    415               double red, double green, double blue);
    416 
    417    void bezier(  int startPtX, int startPtY,
    418               int startControlX, int startControlY,
    419               int endPtX, int endPtY,
    420               int endControlX, int endControlY,
    421               int red, int green, int blue);
    422 
    423    /* Set Text
    424     * Sets the text information in the PNG header. If it is not called, the default is used.
    425     */
    426    void settext(char * title, char * author, char * description, char * software);
    427    void settext(const char * title, const char * author, const char * description, const char * software);
    428 
    429 
    430    /* Version Number
    431     * Returns the PNGwriter version number.
    432     */
    433   static double version(void);
    434 
    435    /* Write PNG
    436     * Writes the PNG image to disk. You can still change the PNGwriter instance after this.
    437     * Tip: This is exactly the same as close(), but easier to remember.
    438     * Tip: To make a sequence of images using only one instance of PNGwriter, alter the image, change its name,
    439     * write_png(), then alter the image, change its name, write_png(), etc.
    440     */
    441    void write_png(void);
    442 
    443    /* Plot Text
    444     * Uses the Freetype2 library to set text in the image. face_path is the file path to a
    445     * TrueType font file (.ttf) (FreeType2 can also handle other types). fontsize specifices the approximate
    446     * height of the rendered font in pixels. x_start and y_start specify the placement of the
    447     * lower, left corner of the text string. angle is the text angle in radians. text is the text to be rendered.
    448     * The colour coordinates can be doubles from 0.0 to 1.0 or ints from 0 to 65535.
    449     * Tip: PNGwriter installs a few fonts in /usr/local/share/pngwriter/fonts to get you started.
    450     * Tip: Remember to add -DNO_FREETYPE to your compilation flags if PNGwriter was compiled without FreeType support.
    451     * */
    452    void plot_text(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double red, double green, double blue);
    453    void plot_text(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, int red, int green, int blue);
    454 
    455 
    456    /* Plot UTF-8 Text
    457     * Same as the above, but the text to be plotted is encoded in UTF-8. Why would you want this? To be able to plot
    458     * all characters available in a large TrueType font, for example: for rendering Japenese, Chinese and other
    459     * languages not restricted to the standard 128 character ASCII space.
    460     * Tip: The quickest way to get a string into UTF-8 is to write it in an adequate text editor, and save it as a file
    461     * in UTF-8 encoding, which can then be read in in binary mode.
    462     * */
    463    void plot_text_utf8(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double red, double green, double blue);
    464    void plot_text_utf8(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, int red, int green, int blue);
    465 
    466 
    467    /* Bilinear Interpolation of Image
    468     * Given a floating point coordinate (x from 0.0 to width, y from 0.0 to height),
    469     * this function will return the interpolated colour intensity specified by
    470     * colour (where red = 1, green = 2, blue = 3).
    471     * bilinear_interpolate_read() returns an int from 0 to 65535, and
    472     * bilinear_interpolate_dread() returns a double from 0.0 to 1.0.
    473     * Tip: Especially useful for enlarging an image.
    474     * */
    475    int bilinear_interpolation_read(double x, double y, int colour);
    476    double bilinear_interpolation_dread(double x, double y, int colour);
    477 
    478    /* Plot Blend
    479     * Plots the colour given by red, green blue, but blended with the existing pixel
    480     * value at that position. opacity is a double that goes from 0.0 to 1.0.
    481     * 0.0 will not change the pixel at all, and 1.0 will plot the given colour.
    482     * Anything in between will be a blend of both pixel levels. Please note: This is neither
    483 	* alpha channel nor PNG transparency chunk support. This merely blends the plotted pixels.
    484     * */
    485 
    486    void plot_blend(int x, int y, double opacity, int red, int green, int blue);
    487    void plot_blend(int x, int y, double opacity, double red, double green, double blue);
    488 
    489 
    490    /* Invert
    491     * Inverts the image in RGB colourspace.
    492     * */
    493    void invert(void);
    494 
    495    /* Resize Image
    496     * Resizes the PNGwriter instance. Note: All image data is set to black (this is
    497     * a resizing, not a scaling, of the image).
    498     * */
    499    void resize(int width, int height);
    500 
    501    /* Boundary Fill
    502     * All pixels adjacent to the start pixel will be filled with the fill colour, until the boundary colour is encountered.
    503     * For example, calling boundary_fill() with the boundary colour set to red, on a pixel somewhere inside a red circle,
    504     * will fill the entire circle with the desired fill colour. If, on the other hand, the circle is not the boundary colour,
    505     * the rest of the image will be filled.
    506     * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535.
    507     * */
    508    void boundary_fill(int xstart, int ystart, double boundary_red,double boundary_green,double boundary_blue,double fill_red, double fill_green, double fill_blue) ;
    509    void boundary_fill(int xstart, int ystart, int boundary_red,int boundary_green,int boundary_blue,int fill_red, int fill_green, int fill_blue) ;
    510 
    511    /* Flood Fill
    512     * All pixels adjacent to the start pixel will be filled with the fill colour, if they are the same colour as the
    513     * start pixel. For example, calling flood_fill() somewhere in the interior of a solid blue rectangle will colour
    514     * the entire rectangle the fill colour. The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535.
    515     * */
    516    void flood_fill(int xstart, int ystart, double fill_red, double fill_green, double fill_blue) ;
    517    void flood_fill(int xstart, int ystart, int fill_red, int fill_green, int fill_blue) ;
    518 
    519    /* Polygon
    520     * This function takes an array of integer values containing the coordinates of the vertexes of a polygon.
    521     * Note that if you want a closed polygon, you must repeat the first point's coordinates for the last point.
    522     * It also requires the number of points contained in the array. For example, if you wish to plot a triangle,
    523     * the array will contain 6 elements, and the number of points is 3. Be very careful about this; if you specify the wrong number
    524     * of points, your program will either segfault or produce points at nonsensical coordinates.
    525     * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535.
    526     * */
    527    void polygon(int * points, int number_of_points, double red, double green, double blue);
    528    void polygon(int * points, int number_of_points, int red, int green, int blue);
    529 
    530    /* Plot CMYK
    531     * Plot a point in the Cyan, Magenta, Yellow, Black colourspace. Please note that this colourspace is
    532     * lossy, i.e. it cannot reproduce all colours on screen that RGB can. The difference, however, is
    533     * barely noticeable. The algorithm used is a standard one. The colour components are either
    534     * doubles from 0.0 to 1.0 or ints from 0 to 65535.
    535     * */
    536    void plotCMYK(int x, int y, double cyan, double magenta, double yellow, double black);
    537    void plotCMYK(int x, int y, int cyan, int magenta, int yellow, int black);
    538 
    539    /* Read CMYK, Double version
    540     * Get a pixel in the Cyan, Magenta, Yellow, Black colourspace. if 'colour' is 1, the Cyan component will be returned
    541     * as a double from 0.0 to 1.0. If 'colour is 2, the Magenta colour component will be returned, and so on, up to 4.
    542     * */
    543    double dreadCMYK(int x, int y, int colour);
    544 
    545    /* Read CMYK
    546     * Same as the above, but the colour components returned are an int from 0 to 65535.
    547     * */
    548    int readCMYK(int x, int y, int colour);
    549 
    550    /* Scale Proportional
    551     * Scale the image using bilinear interpolation. If k is greater than 1.0, the image will be enlarged.
    552     * If k is less than 1.0, the image will be shrunk. Negative or null values of k are not allowed.
    553     * The image will be resized and the previous content will be replaced by the scaled image.
    554     * Tip: use getheight() and getwidth() to find out the new width and height of the scaled image.
    555     * Note: After scaling, all images will have a bit depth of 16, even if the original image had
    556     * a bit depth of 8.
    557     * */
    558    void scale_k(double k);
    559 
    560    /* Scale Non-Proportional
    561     * Scale the image using bilinear interpolation, with different horizontal and vertical scale factors.
    562     * */
    563    void scale_kxky(double kx, double ky);
    564 
    565    /* Scale To Target Width and Height
    566     * Scale the image in such a way as to meet the target width and height.
    567     * Tip: if you want to keep the image proportional, scale_k() might be more appropriate.
    568     * */
    569    void scale_wh(int finalwidth, int finalheight);
    570 
    571 
    572    /* Blended Functions
    573     * All these functions are identical to their non-blended types. They take an extra argument, opacity, which is
    574     * a double from 0.0 to 1.0 and represents how much of the original pixel value is retained when plotting the
    575     * new pixel. In other words, if opacity is 0.7, then after plotting, the new pixel will be 30% of the
    576     * original colour the pixel was, and 70% of the new colour, whatever that may be. As usual, each function
    577     * is available in int or double versions.  Please note: This is neither alpha channel nor PNG transparency chunk support. This merely blends the plotted pixels.
    578     * */
    579 
    580    // Start Blended Functions
    581 
    582    void plotHSV_blend(int x, int y, double opacity, double hue, double saturation, double value);
    583    void plotHSV_blend(int x, int y, double opacity, int hue, int saturation, int value);
    584 
    585    void line_blend(int xfrom, int yfrom, int xto, int yto,  double opacity, int red, int green,int  blue);
    586    void line_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double  blue);
    587 
    588    void square_blend(int xfrom, int yfrom, int xto, int yto, double opacity, int red, int green,int  blue);
    589    void square_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double  blue);
    590 
    591    void filledsquare_blend(int xfrom, int yfrom, int xto, int yto, double opacity, int red, int green,int  blue);
    592    void filledsquare_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double  blue);
    593 
    594    void circle_blend(int xcentre, int ycentre, int radius, double opacity, int red, int green, int blue);
    595    void circle_blend(int xcentre, int ycentre, int radius, double opacity, double red, double green, double blue);
    596 
    597    void filledcircle_blend(int xcentre, int ycentre, int radius, double opacity, int red, int green, int blue);
    598    void filledcircle_blend(int xcentre, int ycentre, int radius, double opacity, double red, double green, double blue);
    599 
    600    void bezier_blend(  int startPtX, int startPtY,
    601 		       int startControlX, int startControlY,
    602 		       int endPtX, int endPtY,
    603 		       int endControlX, int endControlY,
    604 		       double opacity,
    605 		       double red, double green, double blue);
    606 
    607    void bezier_blend(  int startPtX, int startPtY,
    608 		       int startControlX, int startControlY,
    609 		       int endPtX, int endPtY,
    610 		       int endControlX, int endControlY,
    611 		       double opacity,
    612 		       int red, int green, int blue);
    613 
    614    void plot_text_blend(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double opacity, double red, double green, double blue);
    615    void plot_text_blend(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double opacity, int red, int green, int blue);
    616 
    617    void plot_text_utf8_blend(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double opacity, double red, double green, double blue);
    618    void plot_text_utf8_blend(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double opacity, int red, int green, int blue);
    619 
    620    void boundary_fill_blend(int xstart, int ystart, double opacity, double boundary_red,double boundary_green,double boundary_blue,double fill_red, double fill_green, double fill_blue) ;
    621    void boundary_fill_blend(int xstart, int ystart, double opacity, int boundary_red,int boundary_green,int boundary_blue,int fill_red, int fill_green, int fill_blue) ;
    622 
    623    void flood_fill_blend(int xstart, int ystart, double opacity, double fill_red, double fill_green, double fill_blue) ;
    624    void flood_fill_blend(int xstart, int ystart, double opacity, int fill_red, int fill_green, int fill_blue) ;
    625 
    626    void polygon_blend(int * points, int number_of_points, double opacity, double red, double green, double blue);
    627    void polygon_blend(int * points, int number_of_points, double opacity,  int red, int green, int blue);
    628 
    629    void plotCMYK_blend(int x, int y, double opacity, double cyan, double magenta, double yellow, double black);
    630    void plotCMYK_blend(int x, int y, double opacity, int cyan, int magenta, int yellow, int black);
    631 
    632    // End of Blended Functions
    633 
    634    /* Laplacian
    635     * This function applies a discrete laplacian to the image, multiplied by a constant factor.
    636     * The kernel used in this case is:
    637     *                1.0  1.0  1.0
    638     *                1.0 -8.0  1.0
    639     *                1.0  1.0  1.0
    640     * Basically, this works as an edge detector. The current pixel is assigned the sum of all neighbouring
    641     * pixels, multiplied by the corresponding kernel element. For example, imagine a pixel and its 8 neighbours:
    642     *                1.0    1.0    0.0  0.0
    643     *                1.0  ->1.0<-  0.0  0.0
    644     *                1.0    1.0    0.0  0.0
    645     * This represents a border between white and black, black is on the right. Applying the laplacian to
    646     * the pixel specified above pixel gives:
    647     *                1.0*1.0  + 1.0*1.0  + 0.0*1.0 +
    648     *                1.0*1.0  + 1.0*-8.0 + 0.0*1.0 +
    649     *                1.0*1.0  + 1.0*1.0  + 0.0*1.0   = -3.0
    650     * Applying this to the pixel to the right of the pixel considered previously, we get a sum of 3.0.
    651     * That is, after passing over an edge, we get a high value for the pixel adjacent to the edge. Since
    652     * PNGwriter limits the colour components if they are off-scale, and the result of the laplacian
    653     * may be negative, a scale factor and an offset value are included. This might be useful for
    654     * keeping things within range or for bringing out more detail in the edge detection. The
    655     * final pixel value will be given by:
    656     *   final value =  laplacian(original pixel)*k + offset
    657     * Tip: Try a value of 1.0 for k to start with, and then experiment with other values.
    658     * */
    659     void laplacian(double k, double offset);
    660 
    661    /* Filled Triangle
    662     * Draws the triangle specified by the three pairs of points in the colour specified
    663     * by the colour coefficients. The colour components are either doubles from 0.0 to
    664     * 1.0 or ints from 0 to 65535.
    665     * */
    666    void filledtriangle(int x1,int y1,int x2,int y2,int x3,int y3, int red, int green, int blue);
    667    void filledtriangle(int x1,int y1,int x2,int y2,int x3,int y3, double red, double green, double blue);
    668 
    669    /* Filled Triangle, Blended
    670     * Draws the triangle specified by the three pairs of points in the colour specified
    671     * by the colour coefficients, and blended with the background. See the description for Blended Functions.
    672     * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535.
    673     * */
    674    void filledtriangle_blend(int x1,int y1,int x2,int y2,int x3,int y3, double opacity, int red, int green, int blue);
    675    void filledtriangle_blend(int x1,int y1,int x2,int y2,int x3,int y3, double opacity, double red, double green, double blue);
    676 
    677    /* Arrow,  Filled Arrow
    678     * Plots an arrow from (x1, y1) to (x2, y2) with the arrowhead at the second point, given the size in pixels
    679     * and the angle in radians of the arrowhead. The plotted arrow consists of one main line, and two smaller
    680     * lines originating from the second point. Filled Arrow plots the same, but the arrowhead is a solid triangle.
    681     * Tip: An angle of 10 to 30 degrees looks OK.
    682     * */
    683 
    684    void arrow( int x1,int y1,int x2,int y2,int size, double head_angle, double red, double green, double blue);
    685    void arrow( int x1,int y1,int x2,int y2,int size, double head_angle, int red, int green, int blue);
    686 
    687    void filledarrow( int x1,int y1,int x2,int y2,int size, double head_angle, double red, double green, double blue);
    688    void filledarrow( int x1,int y1,int x2,int y2,int size, double head_angle, int red, int green, int blue);
    689 
    690    /* Cross, Maltese Cross
    691     * Plots a simple cross at x, y, with the specified height and width, and in the specified colour.
    692     * Maltese cross plots a cross, as before, but adds bars at the end of each arm of the cross.
    693     * The size of these bars is specified with x_bar_height and y_bar_width.
    694     * The cross will look something like this:
    695     *
    696     *    -----  <-- ( y_bar_width)
    697     *      |
    698     *      |
    699     *  |-------|  <-- ( x_bar_height )
    700     *      |
    701     *      |
    702     *    -----
    703     * */
    704 
    705    void cross( int x, int y, int xwidth, int yheight, double red, double green, double blue);
    706    void cross( int x, int y, int xwidth, int yheight, int red, int green, int blue);
    707 
    708    void maltesecross( int x, int y, int xwidth, int yheight, int x_bar_height, int y_bar_width, double red, double green, double blue);
    709    void maltesecross( int x, int y, int xwidth, int yheight, int x_bar_height, int y_bar_width, int red, int green, int blue);
    710 
    711    /* Diamond and filled diamond
    712     * Plots a diamond shape, given the x, y position, the width and height, and the colour.
    713     * Filled diamond plots a filled diamond.
    714     * */
    715 
    716    void filleddiamond( int x, int y, int width, int height, int red, int green, int blue);
    717    void diamond(int x, int y, int width, int height, int red, int green, int blue);
    718 
    719    void filleddiamond( int x, int y, int width, int height, double red, double green, double blue);
    720    void diamond(int x, int y, int width, int height, double red, double green, double blue);
    721 
    722    /* Get Text Width, Get Text Width UTF8
    723     * Returns the approximate width, in pixels, of the specified *unrotated* text. It is calculated by adding
    724     * each letter's width and kerning value (as specified in the TTF file). Note that this will not
    725     * give the position of the farthest pixel, but it will give a pretty good idea of what area the
    726     * text will occupy. Tip: The text, when plotted unrotated, will fit approximately in a box with its lower left corner at
    727     * (x_start, y_start) and upper right at (x_start + width, y_start + size), where width is given by get_text_width()
    728     * and size is the specified size of the text to be plotted. Tip: Text plotted at position
    729     * (x_start, y_start), rotated with a given 'angle', and of a given 'size'
    730     * whose width is 'width', will fit approximately inside a rectangle whose corners are at
    731     *     1  (x_start, y_start)
    732     *     2  (x_start + width*cos(angle), y_start + width*sin(angle))
    733     *     3  (x_start + width*cos(angle) - size*sin(angle), y_start + width*sin(angle) + size*cos(angle))
    734     *     4  (x_start - size*sin(angle), y_start + size*cos(angle))
    735     * */
    736 
    737    int get_text_width(char * face_path, int fontsize,  char * text);
    738 
    739    int get_text_width_utf8(char * face_path, int fontsize, char * text);
    740 
    741 
    742 };
    743 
    744 
    745 #endif
    746