Actually, GdkPixbuf is a two dimensional array by itself, so we do not need waterfall[i][j] anymore. A single line buffer, waterfall2[j], will suffice.
for(int i=0; i<2;i++) {
p = gdk_pixbuf_get_pixels(pixbuf) + (iwater + i * WATERFALL_YSIZE) * rowstride;
for(int j=0;j<WATERFALL_XSIZE;j++) {
double tmp = waterfall2[j];
*p++ = colormap_r(tmp);
*p++ = colormap_g(tmp);
*p++ = colormap_b(tmp);
}
}
background = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, WATERFALL_XSIZE, WATERFALL_YSIZE);
scale_x = 3.0;
scale_y = 1.0;
offset_x = 0;
offset_y = -(iwater+1);
dest_x = 0;
dest_y = 0;
dest_width = w;
dest_height = WATERFALL_YSIZE;
gdk_pixbuf_composite(pixbuf, background, dest_x, dest_y, dest_width, dest_height, offset_x, offset_y, scale_x, scale_y, GDK_INTERP_BILINEAR, 255);
iwater++;
if (iwater >= WATERFALL_YSIZE) iwater = 0;
In the first step, pixbuf, which is twice as large as minimally required, is updated in two locations. This is a redundant operation, but in this way, a scroll up is implemented with a single copy, gdk_pixbuf_composite().