main.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * MODULE: g.ppmtopng
  3. * AUTHOR(S): Glynn Clements
  4. * PURPOSE: g.ppmtopng isn't meant for end users. It's an internal tool for use by
  5. * the script to generate thumbnails for the r.colors manual page.
  6. * COPYRIGHT: (C) 2009 by Glynn Clements and the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public
  9. * License (>=v2). Read the file COPYING that comes with GRASS
  10. * for details.
  11. *
  12. */
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <stdarg.h>
  16. #include <string.h>
  17. #include <png.h>
  18. #include <grass/gis.h>
  19. #include <grass/glocale.h>
  20. static int width, height;
  21. static unsigned char *buf;
  22. static void read_ppm(const char *filename)
  23. {
  24. FILE *input;
  25. int x, y;
  26. int maxval;
  27. unsigned char *p;
  28. input = fopen(filename, "rb");
  29. if (!input)
  30. G_fatal_error(_("Unable to open input file %s"), filename);
  31. if (fscanf(input, "P6 %d %d %d", &width, &height, &maxval) != 3)
  32. G_fatal_error(_("Invalid input file %s"), filename);
  33. fgetc(input);
  34. buf = G_malloc(width * height * 3);
  35. p = buf;
  36. for (y = 0; y < height; y++) {
  37. for (x = 0; x < width; x++) {
  38. int r = fgetc(input);
  39. int g = fgetc(input);
  40. int b = fgetc(input);
  41. *p++ = (unsigned char) (r * 255 / maxval);
  42. *p++ = (unsigned char) (g * 255 / maxval);
  43. *p++ = (unsigned char) (b * 255 / maxval);
  44. }
  45. }
  46. fclose(input);
  47. }
  48. static void write_png(const char *filename)
  49. {
  50. static jmp_buf jbuf;
  51. static png_struct *png_ptr;
  52. static png_info *info_ptr;
  53. FILE *output;
  54. int y;
  55. unsigned char *p;
  56. png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &jbuf, NULL, NULL);
  57. if (!png_ptr)
  58. G_fatal_error(_("Unable to allocate PNG structure"));
  59. info_ptr = png_create_info_struct(png_ptr);
  60. if (!info_ptr)
  61. G_fatal_error(_("Unable to allocate PNG structure"));
  62. if (setjmp(png_jmpbuf(png_ptr)))
  63. G_fatal_error(_("Error writing PNG file"));
  64. output = fopen(filename, "wb");
  65. if (!output)
  66. G_fatal_error(_("Unable to open output file %s"), filename);
  67. png_init_io(png_ptr, output);
  68. png_set_IHDR(png_ptr, info_ptr,
  69. width, height,
  70. 8, PNG_COLOR_TYPE_RGB,
  71. PNG_INTERLACE_NONE,
  72. PNG_COMPRESSION_TYPE_DEFAULT,
  73. PNG_FILTER_TYPE_DEFAULT);
  74. png_set_invert_alpha(png_ptr);
  75. png_write_info(png_ptr, info_ptr);
  76. for (y = 0, p = buf; y < height; y++, p += 3 * width)
  77. png_write_row(png_ptr, p);
  78. png_write_end(png_ptr, info_ptr);
  79. png_destroy_write_struct(&png_ptr, &info_ptr);
  80. fclose(output);
  81. }
  82. int main(int argc, char *argv[])
  83. {
  84. struct GModule *module;
  85. struct
  86. {
  87. struct Option *in, *out;
  88. } opt;
  89. G_gisinit(argv[0]);
  90. module = G_define_module();
  91. G_add_keyword(_("general"));
  92. G_add_keyword(_("display"));
  93. module->description = _("Converts between PPM/PGM and PNG image formats.");
  94. opt.in = G_define_standard_option(G_OPT_F_INPUT);
  95. opt.out = G_define_standard_option(G_OPT_F_OUTPUT);
  96. if (G_parser(argc, argv))
  97. exit(EXIT_FAILURE);
  98. read_ppm(opt.in->answer);
  99. write_png(opt.out->answer);
  100. return 0;
  101. }