pngwriter.h 39 KB

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