Deplane! Deplane! (Or: RGBRGBRGB => RRRGGGBBB?) Imagine bytes in memory for an RGB image--R and G and B represented by bytes in sequence.  If an image is NxM then the memory layout will be M repetitions for vertical scanlines of 3*N bytes in sequence for the horizontal pixels.  (As one might expect.)

A mandate has come down from on high that you need to be able to isolate contiguous color planes.  You might be asked for the R, G, or B plane.  When you give back the plane it must be the N*M bytes in sequence for that color.

Yet there is a twist: You cannot use additional memory proportional to the size of the image.  Thus you must shuffle the bytes somewhere inside of the existing RGB data to provide the contiguous plane for the requested color.  And you must be able to recover the original image when processing of that color plane is finished.

The image size is actually not relevant to the problem as it operates on the buffer as a whole.  Input is bytes (expressed as hexadecimal ASCII) followed by which plane to extract:

00112233445566778899AABBCCDDEE
G


Output is the extracted color plane, then the original input *(also in hexadecimal ASCII):

114477AADD
00112233445566778899AABBCCDDEE


Where you shuffle the memory is up to you.  But you must actually shuffle the data to produce contiguous bytes (requiring the client to use an iterator is cheating).  And you must be able to reverse the operation to restore the original information.

Lowest big-O implementation wins.  Between two implementations with equal big-O performance... winner decided by code golf rules.
C

only shuffle, not print

lenght in bytes, not pixels

plane: 0,1,2 for R,G,B

not checked!

void deplane(unsigned char *data, int length, int plane) {
    unsigned char *t = data;
    unsigned char *s = data + plane;
    unsigned char p;
    while (s &lt; data + length) {
        p = *s; *s = *t; *t = p;
        t++; s += 3;
    }
    // now plane start at data
    while (t &gt; data) {
        s -= 3; t--;
        p = *s; *s = *t; *t = p;
    }
    // back to original
}