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().