Raster.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <string.h>
  2. #include <math.h>
  3. #include <grass/gis.h>
  4. #include "driver.h"
  5. #include "pngdriver.h"
  6. #ifndef min
  7. #define min(a,b) ((a)<(b)?(a):(b))
  8. #endif
  9. #ifndef max
  10. #define max(a,b) ((a)>(b)?(a):(b))
  11. #endif
  12. static int *trans;
  13. static int ncols;
  14. static int nalloc;
  15. static int masked;
  16. static int src[2][2];
  17. static int dst[2][2];
  18. static double scale(double k, const int src[2], const int dst[2])
  19. {
  20. return dst[0] + (double)(k - src[0]) * (dst[1] - dst[0]) / (src[1] -
  21. src[0]);
  22. }
  23. static int scale_fwd_y(int sy)
  24. {
  25. return (int)floor(scale(sy, src[1], dst[1]) + 0.5);
  26. }
  27. static int scale_rev_x(int dx)
  28. {
  29. return (int)floor(scale(dx + 0.5, dst[0], src[0]));
  30. }
  31. static int next_row(int sy, int dy)
  32. {
  33. sy++;
  34. for (;;) {
  35. int y = scale_fwd_y(sy);
  36. if (y > dy)
  37. return sy - 1;
  38. sy++;
  39. }
  40. }
  41. static void alloc_buffers(void)
  42. {
  43. if (nalloc >= ncols)
  44. return;
  45. nalloc = ncols;
  46. trans = G_realloc(trans, nalloc * sizeof(int));
  47. }
  48. void PNG_begin_raster(int mask, int s[2][2], double fd[2][2])
  49. {
  50. int d[2][2];
  51. int i;
  52. d[0][0] = (int) floor(fd[0][0] + 0.5);
  53. d[0][1] = (int) floor(fd[0][1] + 0.5);
  54. d[1][0] = (int) floor(fd[1][0] + 0.5);
  55. d[1][1] = (int) floor(fd[1][1] + 0.5);
  56. ncols = d[0][1] - d[0][0];
  57. memcpy(src, s, sizeof(src));
  58. memcpy(dst, d, sizeof(dst));
  59. masked = mask;
  60. alloc_buffers();
  61. for (i = 0; i < ncols; i++)
  62. trans[i] = scale_rev_x(d[0][0] + i);
  63. }
  64. int PNG_raster(int n, int row,
  65. const unsigned char *red, const unsigned char *grn,
  66. const unsigned char *blu, const unsigned char *nul)
  67. {
  68. int d_y0 = scale_fwd_y(row + 0);
  69. int d_y1 = scale_fwd_y(row + 1);
  70. int d_rows = d_y1 - d_y0;
  71. int x0 = max(png.clip_left - dst[0][0], 0);
  72. int x1 = min(png.clip_rite - dst[0][0], ncols);
  73. int y0 = max(png.clip_top - d_y0, 0);
  74. int y1 = min(png.clip_bot - d_y0, d_rows);
  75. int x, y;
  76. if (y1 <= y0)
  77. return next_row(row, d_y0);
  78. for (x = x0; x < x1; x++) {
  79. int xx = dst[0][0] + x;
  80. int j = trans[x];
  81. int c;
  82. if (masked && nul && nul[j])
  83. continue;
  84. c = png_get_color(red[j], grn[j], blu[j], 0);
  85. for (y = y0; y < y1; y++) {
  86. int yy = d_y0 + y;
  87. png.grid[yy * png.width + xx] = c;
  88. }
  89. }
  90. png.modified = 1;
  91. return next_row(row, d_y1);
  92. }