docs: private void readTrueColor(ImageReadParam pParam, final ImageInputStream pInput) throws IOException {
          final int width = header.width;
          final int height = header.height;
  
          final Rectangle aoi = getSourceRegion(pParam, width, height);
          final Point offset = pParam == null ? new Point(0, 0) : pParam.getDestinationOffset();
  
          // Set everything to default values
          int sourceXSubsampling = 1;
          int sourceYSubsampling = 1;
          int[] sourceBands = null;
          int[] destinationBands = null;
  
          // Get values from the ImageReadParam, if any
          if (pParam != null) {
              sourceXSubsampling = pParam.getSourceXSubsampling();
              sourceYSubsampling = pParam.getSourceYSubsampling();
  
              sourceBands = pParam.getSourceBands();
              destinationBands = pParam.getDestinationBands();
          }
  
          // Ensure band settings from param are compatible with images
          checkReadParamBandSettings(pParam, header.bitplanes / 8, image.getSampleModel().getNumBands());
  
          // NOTE:  Each row of the image is stored in an integral number of 16 bit words.
          // The number of words per row is words=((w+15)/16)
          int planeWidth = 2 * ((width + 15) / 16);
          final byte[] planeData = new byte[8 * planeWidth];
  
          WritableRaster destination = image.getRaster();
          if (destinationBands != null || offset.x != 0 || offset.y != 0) {
              destination = destination.createWritableChild(0, 0, destination.getWidth(), destination.getHeight(), offset.x, offset.y, destinationBands);
          }
  //        WritableRaster raster = image.getRaster().createCompatibleWritableRaster(width, 1);
          WritableRaster raster = image.getRaster().createCompatibleWritableRaster(8 * planeWidth, 1);
          Raster sourceRow = raster.createChild(aoi.x, 0, aoi.width, 1, 0, 0, sourceBands);
  
          final byte[] data = ((DataBufferByte) raster.getDataBuffer()).getData();
          final int channels = (header.bitplanes + 7) / 8;
          final int planesPerChannel = 8;
          Object dataElements = null;
  
          for (int srcY = 0; srcY < height; srcY++) {
              for (int c = 0; c < channels; c++) {
                  for (int p = 0; p < planesPerChannel; p++) {
                      readPlaneData(pInput, planeData, p * planeWidth, planeWidth);
                  }
  
                  // Skip rows outside AOI
                  if (srcY >= (aoi.y + aoi.height)) {
                      return;
                  }
                  else if (srcY < aoi.y || (srcY - aoi.y) % sourceYSubsampling != 0) {
                      continue;
                  }
  
                  if (formType == IFF.TYPE_ILBM) {
                      // NOTE: Using (channels - c - 1) instead of just c,
                      // effectively reverses the channel order from RGBA to ABGR
                      int off = (channels - c - 1);
  
                      int pixelPos = 0;
                      for (int planePos = 0; planePos < planeWidth; planePos++) {
                          IFFUtil.bitRotateCW(planeData, planePos, planeWidth, data, off + pixelPos * channels, channels);
                          pixelPos += 8;
                      }
                  }
                  else if (formType == IFF.TYPE_PBM) {
                      System.arraycopy(planeData, 0, data, srcY * 8 * planeWidth, planeWidth);
                  }
                  else {
                      throw new AssertionError(String.format("Unsupported FORM type: %s", formType));
                  }
              }
  
              if (srcY >= aoi.y && (srcY - aoi.y) % sourceYSubsampling == 0) {
                  int dstY = (srcY - aoi.y) / sourceYSubsampling;
                  // TODO: Support conversion to INT (A)RGB rasters (maybe using ColorConvertOp?)
                  // TODO: Avoid createChild if no region?
                  if (sourceXSubsampling == 1) {
                      destination.setRect(0, dstY, sourceRow);
  //                dataElements = raster.getDataElements(aoi.x, 0, aoi.width, 1, dataElements);
  //                destination.setDataElements(offset.x, offset.y + (srcY - aoi.y) / sourceYSubsampling, aoi.width, 1, dataElements);
                  }
                  else {
                      for (int srcX = 0; srcX < sourceRow.getWidth(); srcX += sourceXSubsampling) {
                          dataElements = sourceRow.getDataElements(srcX, 0, dataElements);
                          int dstX = srcX / sourceXSubsampling;
                          destination.setDataElements(dstX, dstY, dataElements);
                      }
                  }
              }
  
              processImageProgress(srcY * 100f / header.width);
              if (abortRequested()) {
                  processReadAborted();
                  break;
              }
          }
      }