diff options
author | Carl Hetherington <carl@carlh.net> | 2009-04-30 18:45:45 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2009-04-30 18:45:45 +0000 |
commit | c724b85839d8869a7b08470e11e42e741db46322 (patch) | |
tree | 06a6fff00e4ed5b0c5286e0e8f0bc974a9799b72 /gtk2_ardour/canvas-waveview.c | |
parent | 62fe887e24db45573a1b290fa40af787c99aed2a (diff) |
Fix a couple of valgrind-spotted out-of-bounds accesses that may have been causing segfaults, especially when opening the crossfade editor dialog. Some minor cleanups. Add some comments.
git-svn-id: svn://localhost/ardour2/branches/3.0@5020 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/canvas-waveview.c')
-rw-r--r-- | gtk2_ardour/canvas-waveview.c | 78 |
1 files changed, 43 insertions, 35 deletions
diff --git a/gtk2_ardour/canvas-waveview.c b/gtk2_ardour/canvas-waveview.c index 5c67044084..5563fe5a78 100644 --- a/gtk2_ardour/canvas-waveview.c +++ b/gtk2_ardour/canvas-waveview.c @@ -392,6 +392,7 @@ gnome_canvas_waveview_destroy (GtkObject *object) #define DEBUG_CACHE 0 #undef CACHE_MEMMOVE_OPTIMIZATION +/** @return cache index of start_sample within the cache */ static gint32 gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_sample, gulong end_sample) { @@ -438,7 +439,7 @@ gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_ /* Note the assumption that we have a 1:1 units:pixel ratio for the canvas. Its everywhere ... */ half_width = (gulong) floor ((waveview->screen_width * waveview->samples_per_unit)/2.0 + 0.5); - + if (start_sample < half_width) { new_cache_start = 0; } else { @@ -1091,8 +1092,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, int pymin, pymax; int cache_index; double half_height; - int x, end, begin; - int zbegin, zend; + int x; char rectify; waveview = GNOME_CANVAS_WAVEVIEW (item); @@ -1108,31 +1108,29 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, buf->is_bg = FALSE; } - begin = MAX(waveview->bbox_ulx, buf->rect.x0); + /* a "unit" means a pixel */ - if (begin == waveview->bbox_ulx) { - zbegin = begin + 1; - } else { - zbegin = begin; - } + /* begin: render start x (units) */ + int const begin = MAX (waveview->bbox_ulx, buf->rect.x0); - if (waveview->bbox_lrx >= 0) { - end = MIN(waveview->bbox_lrx,buf->rect.x1); - } else { - end = buf->rect.x1; - } + /* zbegin: start x for zero line (units) */ + int const zbegin = (begin == waveview->bbox_ulx) ? (begin + 1) : begin; - if (end == waveview->bbox_lrx) { - zend = end - 1; - } else { - zend = end; - } + /* end: render end x (units) */ + int const end = (waveview->bbox_lrx >= 0) ? MIN (waveview->bbox_lrx,buf->rect.x1) : buf->rect.x1; + + /* zend: end x for zero-line (units) */ + int const zend = (end == waveview->bbox_lrx) ? (end - 1) : end; if (begin == end) { return; } - s1 = floor ((begin - waveview->bbox_ulx) * waveview->samples_per_unit) ; + /* s1: start sample + s2: end sample + */ + + s1 = floor ((begin - waveview->bbox_ulx) * waveview->samples_per_unit); // fprintf (stderr, "0x%x begins at sample %f\n", waveview, waveview->bbox_ulx * waveview->samples_per_unit); @@ -1176,7 +1174,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, // check_cache (waveview, "post-ensure"); /* don't rectify at single-sample zoom */ - if(waveview->rectified && waveview->samples_per_unit > 1) { + if (waveview->rectified && waveview->samples_per_unit > 1) { rectify = TRUE; } else { @@ -1195,7 +1193,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, /* this makes it slightly easier to comprehend whats going on */ #define origin half_height - if(waveview->filled && !rectify) { + if (waveview->filled && !rectify) { int prev_pymin = 1; int prev_pymax = 0; int last_pymin = 1; @@ -1205,7 +1203,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, int next_clip_max = 0; int next_clip_min = 0; - if(s1 < waveview->samples_per_unit) { + if (s1 < waveview->samples_per_unit) { /* we haven't got a prev vars to compare with, so outline the whole line here */ prev_pymax = (int) rint ((item->y1 + origin) * item->canvas->pixels_per_unit); prev_pymin = prev_pymax; @@ -1229,6 +1227,7 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, * Compute the variables outside the rendering rect */ if(prev_pymax != prev_pymin) { + prev_pymax = (int) rint ((item->y1 + origin - MIN(waveview->cache->data[cache_index].max, 1.0) * half_height) * item->canvas->pixels_per_unit); prev_pymin = (int) rint ((item->y1 + origin - MAX(waveview->cache->data[cache_index].min, -1.0) * half_height) * item->canvas->pixels_per_unit); ++cache_index; @@ -1236,9 +1235,21 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, if(last_pymax != last_pymin) { /* take the index of one sample right of what we render */ int index = cache_index + (end - begin); - - last_pymax = (int) rint ((item->y1 + origin - MIN(waveview->cache->data[index].max, 1.0) * half_height) * item->canvas->pixels_per_unit); - last_pymin = (int) rint ((item->y1 + origin - MAX(waveview->cache->data[index].min, -1.0) * half_height) * item->canvas->pixels_per_unit); + + if (index >= waveview->cache->data_size) { + + /* the data we want is off the end of the cache, which must mean its beyond + the end of the region's source; hence the peak values are 0 */ + last_pymax = (int) rint ((item->y1 + origin) * item->canvas->pixels_per_unit); + last_pymin = (int) rint ((item->y1 + origin) * item->canvas->pixels_per_unit); + + } else { + + last_pymax = (int) rint ((item->y1 + origin - MIN(waveview->cache->data[index].max, 1.0) * half_height) * item->canvas->pixels_per_unit); + last_pymin = (int) rint ((item->y1 + origin - MAX(waveview->cache->data[index].min, -1.0) * half_height) * item->canvas->pixels_per_unit); + + } + } /* @@ -1283,8 +1294,12 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, else { ++cache_index; - max = waveview->cache->data[cache_index].max; - min = waveview->cache->data[cache_index].min; + if (cache_index < waveview->cache->data_size) { + max = waveview->cache->data[cache_index].max; + min = waveview->cache->data[cache_index].min; + } else { + max = min = 0; + } next_clip_max = 0; next_clip_min = 0; @@ -1611,7 +1626,6 @@ gnome_canvas_waveview_draw (GnomeCanvasItem *item, cairo_t* cr; gulong s1, s2; int cache_index; - double zbegin, zend; gboolean rectify; double origin; double clip_length; @@ -1630,10 +1644,8 @@ gnome_canvas_waveview_draw (GnomeCanvasItem *item, if (x > waveview->bbox_ulx) { ulx = x; - zbegin = ulx; } else { ulx = waveview->bbox_ulx; - zbegin = ulx + 1; } if (y > waveview->bbox_uly) { @@ -1644,10 +1656,8 @@ gnome_canvas_waveview_draw (GnomeCanvasItem *item, if (x + width > waveview->bbox_lrx) { lrx = waveview->bbox_lrx; - zend = lrx - 1; } else { lrx = x + width; - zend = lrx; } if (y + height > waveview->bbox_lry) { @@ -1675,8 +1685,6 @@ gnome_canvas_waveview_draw (GnomeCanvasItem *item, uly -= y; lrx -= x; lry -= y; - zbegin -= x; - zend -= x; /* don't rectify at single-sample zoom */ if(waveview->rectified && waveview->samples_per_unit > 1.0) { |