GRASS Programmer's Manual
6.4.2(2012)
|
00001 00002 #include <string.h> 00003 #include <math.h> 00004 #include <grass/gis.h> 00005 #include "driver.h" 00006 #include "pngdriver.h" 00007 00008 #ifndef min 00009 #define min(a,b) ((a)<(b)?(a):(b)) 00010 #endif 00011 #ifndef max 00012 #define max(a,b) ((a)>(b)?(a):(b)) 00013 #endif 00014 00015 static int *trans; 00016 static int ncols; 00017 static int nalloc; 00018 static int masked; 00019 static int src[2][2]; 00020 static int dst[2][2]; 00021 00022 static double scale(double k, const int src[2], const int dst[2]) 00023 { 00024 return dst[0] + (double)(k - src[0]) * (dst[1] - dst[0]) / (src[1] - 00025 src[0]); 00026 } 00027 00028 static int scale_fwd_y(int sy) 00029 { 00030 return (int)floor(scale(sy, src[1], dst[1]) + 0.5); 00031 } 00032 00033 static int scale_rev_x(int dx) 00034 { 00035 return (int)floor(scale(dx + 0.5, dst[0], src[0])); 00036 } 00037 00038 static int next_row(int sy, int dy) 00039 { 00040 sy++; 00041 00042 for (;;) { 00043 int y = scale_fwd_y(sy); 00044 00045 if (y > dy) 00046 return sy - 1; 00047 sy++; 00048 } 00049 } 00050 00051 static void alloc_buffers(void) 00052 { 00053 if (nalloc >= ncols) 00054 return; 00055 00056 nalloc = ncols; 00057 trans = G_realloc(trans, nalloc * sizeof(int)); 00058 } 00059 00060 void PNG_begin_scaled_raster(int mask, int s[2][2], int d[2][2]) 00061 { 00062 int i; 00063 00064 ncols = d[0][1] - d[0][0]; 00065 00066 memcpy(src, s, sizeof(src)); 00067 memcpy(dst, d, sizeof(dst)); 00068 masked = mask; 00069 00070 alloc_buffers(); 00071 00072 for (i = 0; i < ncols; i++) 00073 trans[i] = scale_rev_x(d[0][0] + i); 00074 } 00075 00076 int PNG_scaled_raster(int n, int row, 00077 const unsigned char *red, const unsigned char *grn, 00078 const unsigned char *blu, const unsigned char *nul) 00079 { 00080 int d_y0 = scale_fwd_y(row + 0); 00081 int d_y1 = scale_fwd_y(row + 1); 00082 int d_rows = d_y1 - d_y0; 00083 int x0 = max(clip_left - dst[0][0], 0); 00084 int x1 = min(clip_rite - dst[0][0], ncols); 00085 int y0 = max(clip_top - d_y0, 0); 00086 int y1 = min(clip_bot - d_y0, d_rows); 00087 int x, y; 00088 00089 if (y1 <= y0) 00090 return next_row(row, d_y0); 00091 00092 for (x = x0; x < x1; x++) { 00093 int xx = dst[0][0] + x; 00094 int j = trans[x]; 00095 int c; 00096 00097 if (masked && nul && nul[j]) 00098 continue; 00099 00100 c = get_color(red[j], grn[j], blu[j], 0); 00101 00102 for (y = y0; y < y1; y++) { 00103 int yy = d_y0 + y; 00104 00105 grid[yy * width + xx] = c; 00106 } 00107 } 00108 00109 modified = 1; 00110 00111 return next_row(row, d_y1); 00112 }