[GRASS-SVN] r63595 - in grass/branches/releasebranch_7_0: . lib/cairodriver
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Dec 18 09:04:06 PST 2014
Author: martinl
Date: 2014-12-18 09:04:05 -0800 (Thu, 18 Dec 2014)
New Revision: 63595
Modified:
grass/branches/releasebranch_7_0/
grass/branches/releasebranch_7_0/lib/cairodriver/raster.c
Log:
glynn: Make cairo driver rescale rasters rather than having cairo do it (ticket #2403)
(merge r63582 from trunk)
Property changes on: grass/branches/releasebranch_7_0
___________________________________________________________________
Modified: svn:mergeinfo
- /grass/trunk:60817,61096,61141,61994,62105,62179-62180,62182,62403,62422,62424,62437,62466,62469,62487,62491,62494,62501,62506,62508-62509,62515,62518-62519,62521,62526,62533,62539,62541,62555,62562,62566,62570,62573,62575,62585,62588,62597,62603,62606,62608-62609,62614,62618,62628,62632,62638,62642,62648-62649,62652,62654-62657,62666,62691,62705,62709,62723,62730,62739,62741,62743,62746,62750,62752,62757,62762,62785,62798,62800-62801,62803,62805,62812,62822,62824,62831,62838,62847,62850,62856,62879,62881,62886,62904,62907-62908,62910,62912,62914,62916,62918,62920,62925,62932-62933,62935,62940,62942,62944-62946,62949,62955-62956,62958,62960,62962,62964,62966-62968,62970,62973,62975,62977,62981,62983,62985,62987,62989,62991,62993,62995,62997,62999-63000,63003,63005,63007,63009,63011,63013,63015,63017,63020,63022,63024,63026,63028-63031,63033,63035,63037,63040,63043-63044,63047,63049,63051,63053,63055,63057,63060,63062-63064,63066,63068,63070-63071,63074,63076,63079,63081,
63083,63085,63087,63089,63091,63093,63095,63098,63100,63102,63105,63107,63109,63111,63113-63114,63116,63119,63121,63123,63125,63130,63132-63133,63135,63137,63140,63143,63145,63147,63149,63151,63153-63154,63157,63160,63165,63170,63173,63175,63187,63192-63193,63196,63199-63200,63202,63209,63216,63220-63221,63224,63227,63240,63246,63250,63255,63259,63261,63276,63279,63281,63283,63287,63290,63292,63302,63307,63315,63319,63330,63332,63339,63342,63345,63362,63367,63391,63393,63408-63409,63416-63417,63425,63427,63429,63431,63433,63451,63453,63457,63459,63464-63470,63473,63482,63497,63505,63508,63510,63515,63521-63524,63526,63536-63537,63551-63552,63554,63556,63558-63559,63562,63570,63576,63593
+ /grass/trunk:60817,61096,61141,61994,62105,62179-62180,62182,62403,62422,62424,62437,62466,62469,62487,62491,62494,62501,62506,62508-62509,62515,62518-62519,62521,62526,62533,62539,62541,62555,62562,62566,62570,62573,62575,62585,62588,62597,62603,62606,62608-62609,62614,62618,62628,62632,62638,62642,62648-62649,62652,62654-62657,62666,62691,62705,62709,62723,62730,62739,62741,62743,62746,62750,62752,62757,62762,62785,62798,62800-62801,62803,62805,62812,62822,62824,62831,62838,62847,62850,62856,62879,62881,62886,62904,62907-62908,62910,62912,62914,62916,62918,62920,62925,62932-62933,62935,62940,62942,62944-62946,62949,62955-62956,62958,62960,62962,62964,62966-62968,62970,62973,62975,62977,62981,62983,62985,62987,62989,62991,62993,62995,62997,62999-63000,63003,63005,63007,63009,63011,63013,63015,63017,63020,63022,63024,63026,63028-63031,63033,63035,63037,63040,63043-63044,63047,63049,63051,63053,63055,63057,63060,63062-63064,63066,63068,63070-63071,63074,63076,63079,63081,
63083,63085,63087,63089,63091,63093,63095,63098,63100,63102,63105,63107,63109,63111,63113-63114,63116,63119,63121,63123,63125,63130,63132-63133,63135,63137,63140,63143,63145,63147,63149,63151,63153-63154,63157,63160,63165,63170,63173,63175,63187,63192-63193,63196,63199-63200,63202,63209,63216,63220-63221,63224,63227,63240,63246,63250,63255,63259,63261,63276,63279,63281,63283,63287,63290,63292,63302,63307,63315,63319,63330,63332,63339,63342,63345,63362,63367,63391,63393,63408-63409,63416-63417,63425,63427,63429,63431,63433,63448,63451,63453,63457,63459,63464-63470,63473,63482,63497,63505,63508,63510,63515,63521-63524,63526,63536-63537,63551-63552,63554,63556,63558-63559,63562,63570,63576,63582,63593
Modified: grass/branches/releasebranch_7_0/lib/cairodriver/raster.c
===================================================================
--- grass/branches/releasebranch_7_0/lib/cairodriver/raster.c 2014-12-18 16:29:30 UTC (rev 63594)
+++ grass/branches/releasebranch_7_0/lib/cairodriver/raster.c 2014-12-18 17:04:05 UTC (rev 63595)
@@ -3,7 +3,7 @@
\brief GRASS cairo display driver - draw raster
- (C) 2007-2008 by Lars Ahlzen and the GRASS Development Team
+ (C) 2007-2014 by Lars Ahlzen and the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@@ -12,39 +12,74 @@
\author Glynn Clements
*/
+#include <math.h>
#include "cairodriver.h"
#include <grass/glocale.h>
+#define MAX_IMAGE_SIZE 32767
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
static int src_t, src_b, src_l, src_r, src_w, src_h;
-static double dst_t, dst_b, dst_l, dst_r, dst_w, dst_h;
+static int dst_t, dst_b, dst_l, dst_r, dst_w, dst_h;
+static int *trans;
+
static cairo_surface_t *src_surf;
static unsigned char *src_data;
-static int src_stride;
+static int src_stride, ca_row;
static int masked;
+static double scale(double k, int src_0, int src_1, int dst_0, int dst_1)
+{
+ return dst_0 + (double) (k - src_0) * (dst_1 - dst_0) / (src_1 - src_0);
+}
+
+static int scale_fwd_y(int sy)
+{
+ return (int)floor(scale(sy, src_t, src_b, dst_t, dst_b) + 0.5);
+}
+
+static int scale_rev_x(int dx)
+{
+ return (int)floor(scale(dx + 0.5, dst_l, dst_r, src_l, src_r));
+}
+
+static int next_row(int sy, int dy)
+{
+ sy++;
+
+ for (;;) {
+ int y = scale_fwd_y(sy);
+
+ if (y > dy)
+ return sy - 1;
+ sy++;
+ }
+}
+
/*!
\brief Start drawing raster
- \param mask
- \param s
- \param d
+ \todo are top and left swapped?
+
+ \param mask non-zero int for mask
+ \param s source (map) extent (left, right, top, bottom)
+ \param d destination (image) extent (left, right, top, bottom)
*/
void Cairo_begin_raster(int mask, int s[2][2], double d[2][2])
{
+ int i;
cairo_status_t status;
- G_debug(1, "Cairo_begin_raster: %d, %d %d %d %d, %f %f %f %f",
- mask,
- s[0][0], s[0][1], s[1][0], s[1][1],
- d[0][0], d[0][1], d[1][0], d[1][1]);
-
masked = mask;
- /* TODO: are top and left swapped? */
-
src_l = s[0][0];
src_r = s[0][1];
src_t = s[1][0];
@@ -53,39 +88,43 @@
src_w = src_r - src_l;
src_h = src_b - src_t;
- dst_l = d[0][0];
- dst_r = d[0][1];
- dst_t = d[1][0];
- dst_b = d[1][1];
+ dst_l = (int) floor(d[0][0] + 0.5);
+ dst_r = (int) floor(d[0][1] + 0.5);
+ dst_t = (int) floor(d[1][0] + 0.5);
+ dst_b = (int) floor(d[1][1] + 0.5);
dst_w = dst_r - dst_l;
dst_h = dst_b - dst_t;
- G_debug(1, " src (TBLR): %d %d %d %d, dst (TBLR) %f %f %f %f",
- src_t, src_b, src_l, src_r, dst_t, dst_b, dst_l, dst_r);
+ G_debug(1, "Cairo_begin_raster(): masked=%d, src_lrtb=%d %d %d %d -> w/h=%d/%d, "
+ "dst_lrtb=%d %d %d %d -> w/h=%d %d",
+ masked, src_l, src_r, src_t, src_b, src_w, src_h,
+ dst_l, dst_r, dst_t, dst_b, dst_w, dst_h);
/* create source surface */
- src_surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, src_w, src_h);
+ src_surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ca.width, ca.height);
status = cairo_surface_status(src_surf);
if (status != CAIRO_STATUS_SUCCESS)
-#ifdef HAVE_LONG_LONG_INT
- G_fatal_error("Cairo_begin_raster(): %s - %s. Using rows: %d, cols: %d, cells: %lld.",
- _("Failed to create surface"),
- cairo_status_to_string (status), src_b, src_r, (long long) src_b * src_r);
-#else
- G_fatal_error("Cairo_begin_raster(): %s - %s. Using rows: %d, cols: %d, cells: %ld.",
- _("Failed to create surface"),
- cairo_status_to_string (status), src_b, src_r, (long) src_b * src_r);
-#endif
+ G_fatal_error("%s - %s - size: %dx%d (cairo limit: %dx%d)",
+ _("Failed to create cairo surface"),
+ cairo_status_to_string (status), ca.width, ca.height,
+ MAX_IMAGE_SIZE, MAX_IMAGE_SIZE);
+
src_data = cairo_image_surface_get_data(src_surf);
src_stride = cairo_image_surface_get_stride(src_surf);
+ ca_row = 0;
+
+ /* allocate buffer for down-sampling data */
+ trans = G_malloc(dst_w * sizeof(int));
+ for (i = 0; i < dst_w; i++)
+ trans[i] = scale_rev_x(dst_l + i);
}
/*!
\brief Draw raster row
- \param n number of cell
- \param row raster row
+ \param n number of cells
+ \param row raster row (starting at 0)
\param red,grn,blu,nul red,green,blue and null value
\return next row
@@ -94,26 +133,45 @@
const unsigned char *red, const unsigned char *grn,
const unsigned char *blu, const unsigned char *nul)
{
- unsigned int *dst =
- (unsigned int *)(src_data + (row - src_t) * src_stride);
- int i;
+ int d_y0 = scale_fwd_y(row + 0);
+ int d_y1 = scale_fwd_y(row + 1);
+ int d_rows = d_y1 - d_y0;
+ int x0 = MAX(0 - dst_l, 0);
+ int x1 = MIN(ca.width - dst_l, dst_w);
+ int y0 = MAX(0 - d_y0, 0);
+ int y1 = MIN(ca.height - d_y0, d_rows);
+ int x, y;
- G_debug(3, "Cairo_raster: %d %d", n, row);
+ if (y1 <= y0)
+ return next_row(row, d_y1);
- for (i = 0; i < n; i++) {
- if (masked && nul && nul[i])
- *dst++ = 0;
+ G_debug(3, "Cairo_raster(): row=%d", row);
+
+ for (x = x0; x < x1; x++) {
+ int xx = dst_l + x;
+ int j = trans[x];
+ unsigned int c;
+
+ if (masked && nul && nul[j])
+ c = 0;
else {
- unsigned int r = red[i];
- unsigned int g = grn[i];
- unsigned int b = blu[i];
+ unsigned int r = red[j];
+ unsigned int g = grn[j];
+ unsigned int b = blu[j];
unsigned int a = 0xFF;
+ c = (a << 24) + (r << 16) + (g << 8) + (b << 0);
+ }
- *dst++ = (a << 24) + (r << 16) + (g << 8) + (b << 0);
- }
+ for (y = y0; y < y1; y++) {
+ int yy = d_y0 + y;
+ *(unsigned int *)(src_data + yy * src_stride + xx * 4) = c;
+ }
}
- return row + 1;
+ ca.modified = 1;
+ ca_row++;
+
+ return next_row(row, d_y1);
}
/*!
@@ -121,12 +179,12 @@
*/
void Cairo_end_raster(void)
{
- G_debug(1, "Cairo_end_raster");
+ G_debug(1, "Cairo_end_raster()");
- /* paint source surface onto dstination (scaled) */
+ /* paint source surface onto destination (scaled) */
cairo_save(cairo);
- cairo_translate(cairo, dst_l, dst_t);
- cairo_scale(cairo, dst_w / src_w, dst_h / src_h);
+ /* cairo_translate(cairo, dst_l, dst_t); */
+ /* cairo_scale(cairo, dst_w / src_w, dst_h / src_h); */
cairo_surface_mark_dirty(src_surf);
cairo_set_source_surface(cairo, src_surf, 0, 0);
cairo_pattern_set_filter(cairo_get_source(cairo), CAIRO_FILTER_NEAREST);
@@ -134,6 +192,7 @@
cairo_restore(cairo);
/* cleanup */
+ G_free(trans);
cairo_surface_destroy(src_surf);
ca.modified = 1;
}
More information about the grass-commit
mailing list