readPixel for NeoMatrix library

Hi all.

I'm looking to write a readPixel function for the Adafruit NeoMatrix library.

So far I have... (which you will note is exactly the same as the drawPixel function just using getPixelColor at the end)

uint32_t Adafruit_NeoMatrix::readPixel(int16_t x, int16_t y) const {

	if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return 0; //specified pixel is outside limits
	
	int16_t t;
  switch(rotation) {
   case 1:
    t = x;
    x = WIDTH  - 1 - y;
    y = t;
    break;
   case 2:
    x = WIDTH  - 1 - x;
    y = HEIGHT - 1 - y;
    break;
   case 3:
    t = x;
    x = y;
    y = HEIGHT - 1 - t;
    break;
  }

  int tileOffset = 0, pixelOffset;

  if(remapFn) { // Custom X/Y remapping function
    pixelOffset = (*remapFn)(x, y);
  } else {      // Standard single matrix or tiled matrices

    uint8_t  corner = type & NEO_MATRIX_CORNER;
    uint16_t minor, major, majorScale;

    if(tilesX) { // Tiled display, multiple matrices
      uint16_t tile;

      minor = x / matrixWidth;            // Tile # X/Y; presume row major to
      major = y / matrixHeight,           // start (will swap later if needed)
      x     = x - (minor * matrixWidth);  // Pixel X/Y within tile
      y     = y - (major * matrixHeight); // (-* is less math than modulo)

      // Determine corner of entry, flip axes if needed
      if(type & NEO_TILE_RIGHT)  minor = tilesX - 1 - minor;
      if(type & NEO_TILE_BOTTOM) major = tilesY - 1 - major;

      // Determine actual major axis of tiling
      if((type & NEO_TILE_AXIS) == NEO_TILE_ROWS) {
        majorScale = tilesX;
      } else {
        swap(major, minor);
        majorScale = tilesY;
      }

      // Determine tile number
      if((type & NEO_TILE_SEQUENCE) == NEO_TILE_PROGRESSIVE) {
        // All tiles in same order
        tile = major * majorScale + minor;
      } else {
        // Zigzag; alternate rows change direction.  On these rows,
        // this also flips the starting corner of the matrix for the
        // pixel math later.
        if(major & 1) {
          corner ^= NEO_MATRIX_CORNER;
          tile = (major + 1) * majorScale - 1 - minor;
        } else {
          tile =  major      * majorScale     + minor;
        }
      }

      // Index of first pixel in tile
      tileOffset = tile * matrixWidth * matrixHeight;

    } // else no tiling (handle as single tile)

    // Find pixel number within tile
    minor = x; // Presume row major to start (will swap later if needed)
    major = y;

    // Determine corner of entry, flip axes if needed
    if(corner & NEO_MATRIX_RIGHT)  minor = matrixWidth  - 1 - minor;
    if(corner & NEO_MATRIX_BOTTOM) major = matrixHeight - 1 - major;

    // Determine actual major axis of matrix
    if((type & NEO_MATRIX_AXIS) == NEO_MATRIX_ROWS) {
      majorScale = matrixWidth;
    } else {
      swap(major, minor);
      majorScale = matrixHeight;
    }

    // Determine pixel number within tile/matrix
    if((type & NEO_MATRIX_SEQUENCE) == NEO_MATRIX_PROGRESSIVE) {
      // All lines in same order
      pixelOffset = major * majorScale + minor;
    } else {
      // Zigzag; alternate rows change direction.
      if(major & 1) pixelOffset = (major + 1) * majorScale - 1 - minor;
      else          pixelOffset =  major      * majorScale     + minor;
    }
  }

  return getPixelColor(tileOffset + pixelOffset);
}

This all compiles fine.

What I am stuck on is essentially all the different colour spaces being used. Within the adafruit implementation they exist as 3x8bit rgb values, 16bit adafruit gfx colourspace and 32bit WS2812 colourspace (which is actually 24bit padded out). You can understand the difficulty I am having getting past this!

So my question is this:
Now that I have my matrix.readPixel(x,y) function how can I implement it with matrix.drawPixel(x,y,c) to simply draw back what has been read?

Further to my last...

The readPixel function works fine. It spits out 32 bits where the first 8 (0-7) are the blue channel, the next 8 (8-15) are green, the next 8 (16-23) red, followed by zeroes to pad it out to 32 (24-31).

To write it back to a pixel I need to use matrix.Color which takes 3 8bit inputs (the three color channels). So the code that I am using to strip the channels out of the 32bit output from readPixel is:

c = readPixel(x,y);
uint8_t
  r = (uint8_t)(c >> 16),
  g = (uint8_t)(c >> 8),
  b = (uint8_t)c;
matrix.drawPixel(x,y,matrix.Color(r,g,b));

If I have color channel data that is all 1's (ie a decimal 255 value either red, blue or green) then the pixel gets read correctly and written back fine. If the data is a mixture of 1s and 0s then as the read and write loops over time the pixels dim until they're off or go through a craze of colors.

Which makes me think that my code to strip the 32bit into 8bit channels is not correct. Any obvious errors in the approach?

Ultimately what I'm aiming to create is the ability to fade pixels over time (visualising trails, etc).