Introduction to 2D Linux Game Programming/Algorithms/Simple Software Transformations/Optimized Integer Scaling
From Wikibooks, open books for an open world
Optimized Image Scaling [edit]
This takes the previous, non-optimzed version of the integer scaling program and changes a few things to make it much quicker.
The Source: [edit]
// IntegerScale.cpp #include <iostream> #include "include/S.h" using namespace std; /************************************************************ * This is the speed optimized version of our IntegerScale() * function. Readability is a distant second to speed. * We pre-calculate everything we can rather than calculating * over and over in the inner for loops. Where we can't * pre-calculate, we move the calculation as "high" up in the * for loop chain as we can. We move definitions of variables * out of the loops so they're defined once rather than every * iteration. Instead of rebuilding a row scale times we * calculate it once, then copy it scale-1 times. It is a * much quicker algorithm, but it's also much more difficult * to read or explain. After seeing the original, unoptomized * scale function, it should be easier to see what this one * is doing. ************************************************************/ int main() { // All the variables that can be pre-calculated // and do not change in the for loops const int width = S::sw(); // The original Array's width const int height = S::sh(width); // The original Array's height const int scale = S::ss(width); // How many times to scale the image const int s_size = width*height; // Size of source image const int widthscale = width*scale; const int scalewidthscale = scale*widthscale; const int heightscale = height*scale; // Our source and destination arrays int source[s_size]; // Original Array int dest[scalewidthscale * height]; // Scaled Array // Pointers for the line we're going to copy int *repeat; // Address of first element of row we're copying int *traverserepeat; // Address of the element we're copying int *traversedest; // Address we're copying to in dest array // Setup our source "image" for(int x = 0; x < s_size; ++x) source[x]=x; cout << "\n\n"; S::print_rect(width, height, &source[0]); cout << "\n\n"; // The following for loop iterators // defined out of the for loop to // avoid recreating them every time // we drop out of the inner loops int hrepeat = 0; // height repeat int w = 0; // width counter int wrepeat = 0; // width repeat // Integers we calculate as high up in the for loops // as possible int hscalewidthscale; // h * scale * width * scale int wscale; // w * scale int hwidth; // h * width for(int h = 0; h < height; ++h) // Source Height Position { hscalewidthscale = h*scalewidthscale; // Set the address of the first element of the array // We're going to copy repeat=&dest[hscalewidthscale]; for(; hrepeat < scale; ++hrepeat) // Repeat a full row scale times { if(hrepeat==0) // This is a new line in the source image { for(; w < width; ++w) // Source width Offset { wscale = w*scale; hwidth = h*width; // Repeat individual pixel scale times for(; wrepeat < scale; ++wrepeat) dest[hscalewidthscale + wscale + wrepeat] = source[ hwidth + w]; wrepeat = 0; } w = 0; } else { // The initial element we're going to copy traverserepeat=repeat; // The initial element to copy to dest[] traversedest=&repeat[hrepeat*widthscale]; for(; w < width; ++w) { wscale = w*scale; for(; wrepeat < scale; ++wrepeat) { // Copy a value into dest[] *traversedest=*traverserepeat; // Traverse the array we're // copying from and into ++traversedest; ++traverserepeat; } wrepeat=0; } w = 0; } } hrepeat = 0; } S::print_rect(widthscale,heightscale,&dest[0]); cout << "\n" << endl; return(0); }
This page may need to be