3
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Surely the G channel of the sample input is 0235689BCE? And does the restriction on additional memory also apply to the print operation, or is that allowed to copy? \$\endgroup\$ – Peter Taylor Jun 19 '14 at 22:00
  • \$\begingroup\$ @petertaylor how do you figure G as not being the second byte and every third byte after? Regarding restrictions just imagine a buffer of a million by a million image... Your print cannot depend on allocations scaling with the image size. \$\endgroup\$ – HostileFork says dont trust SE Jun 19 '14 at 22:12
  • 2
    \$\begingroup\$ Is input in raw bytes, or in the base-16 encoding shown in the examples? (I think that's also @PeterTaylor's question.) \$\endgroup\$ – earl Jun 19 '14 at 22:35
  • \$\begingroup\$ @PeterTaylor Yes, hex strings. Clarified. \$\endgroup\$ – HostileFork says dont trust SE Jun 20 '14 at 9:23
  • 2
    \$\begingroup\$ If they are hex strings, why not simply convert them to raw bytes, and then you'll have a lot of freed memory to do whatever you wish... \$\endgroup\$ – jimmy23013 Jun 20 '14 at 16:49
3
\$\begingroup\$

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 < data + length) {
        p = *s; *s = *t; *t = p;
        t++; s += 3;
    }
    // now plane start at data
    while (t > data) {
        s -= 3; t--;
        p = *s; *s = *t; *t = p;
    }
    // back to original
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ If you are going to golf this code, *s ^= *t; *t ^= *s; (restored by *t ^= *s; *s ^= *t;) can be shorter. But t must start at s+1 this way. \$\endgroup\$ – jimmy23013 Jun 20 '14 at 11:03
  • \$\begingroup\$ Very smart!! But why "t must start at s+1" ? \$\endgroup\$ – giuliolunati Jun 20 '14 at 16:36
  • \$\begingroup\$ If t and s refer to the same memory position, *s ^= *t; will make *s irreversibly zero. You can also skip the first value if this happens. But it may be longer if you treat R plane in a special way. \$\endgroup\$ – jimmy23013 Jun 20 '14 at 16:38
  • \$\begingroup\$ Oh, right! .... \$\endgroup\$ – giuliolunati Jun 20 '14 at 17:33
  • \$\begingroup\$ and the language is ... \$\endgroup\$ – edc65 Jun 21 '14 at 10:03
2
\$\begingroup\$

Javascript (E6)

I don't like the I/O format, these should be byte arrays or the like. Anyway.
Source not golfed.

S=(a,p)=>{
  b = a.match(/../g);    // String to array 
  l = b.length/3;        // Plane size
  s = p<'G'?2:p>'G'?0:1; // Which plane

  for (j=0, i=s; b[i]; j++, i+=3) // Shuffle
    [b[i],b[j]] = [b[j],b[i]];
  console.log(b.slice(0,l).join('')); // Output plane

  for (; i-=3, j--; ) // Unshuffle
    [b[i],b[j]] = [b[j],b[i]];

  console.log(b.join('')) // Original is back         
}  

Usage

In firefox console:

S('00112233445566778899AABBCCDDEE','G')

Output

114477AADD
00112233445566778899AABBCCDDEE
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.