docs: private void readPICTopcodes(ImageInputStream pStream) throws IOException {
          pStream.seek(imageStartStreamPos);
  
          int opCode, dh, dv, dataLength;
          byte[] colorBuffer = new byte[3 * PICT.COLOR_COMP_SIZE];
  
          Pattern fill = QuickDraw.BLACK;
          Pattern bg;
          Pattern pen;
          Color hilight = Color.RED;
  
          Point origin, dh_dv;
          Point ovSize = new Point();
          Point arcAngles = new Point();
          String text;
          Rectangle bounds = new Rectangle();
          Polygon polygon = new Polygon();
          Area region = new Area();
          int pixmapCount = 0;
  
          try {
              // Read from file until we read the end of picture opcode
              do {
                  // Read opcode, version 1: byte, version 2: short
                  if (version == 1) {
                      opCode = pStream.readUnsignedByte();
                  }
                  else {
                      // Always word-aligned for version 2
                      if ((pStream.getStreamPosition() & 1) > 0) {
                          pStream.readByte();
                      }
                      opCode = pStream.readUnsignedShort();
                  }
  
                  // See what we got and react in consequence
                  switch (opCode) {
                      case PICT.NOP:
                          // Just go on
                          if (DEBUG) {
                              System.out.println("NOP");
                          }
                          break;
  
                      case PICT.OP_CLIP_RGN:// OK for RECTS, not for regions yet
                          // Read the region
                          if ((region = readRegion(pStream, bounds)) == null) {
                              throw new IIOException("Could not read region");
                          }
                          // Set clip rect or clip region
  
                          //if (mGraphics != null) {
                          //    if (region.npoints == 0) {
                          //        // TODO: Read what the specs says about this...
                          //        if (bounds.width > 0 && bounds.height > 0) {
                          //            mGraphics.setClip(bounds.x, bounds.y, bounds.width, bounds.height);
                          //        }
                          //    }
                          //    else {
                          //        mGraphics.setClip(region);
                          //    }
                          //}
                          if (DEBUG) {
                              verboseRegionCmd("clipRgn", bounds, region);
                          }
                          break;
  
                      case PICT.OP_BK_PAT:
                          // Get the data
                          context.setBackgroundPattern(PICTUtil.readPattern(pStream));
                          if (DEBUG) {
                              System.out.println("bkPat");
                          }
                          break;
  
                      case PICT.OP_TX_FONT:
                          // Get the data
                          byte[] fontData = new byte[2];
                          pStream.readFully(fontData, 0, 2);
                          // TODO: Font family id, 0 - System font, 1 - Application font.
                          // But how can we get these mappings?
                          if (DEBUG) {
                              System.out.println("txFont: " + Arrays.toString(fontData));
                          }
                          break;
  
                      case PICT.OP_TX_FACE:
                          // Get the data
                          int txFace = pStream.readUnsignedByte();
                          context.setTextFace(txFace);
                          if (DEBUG) {
                              System.out.println("txFace: " + txFace);
                          }
                          break;
  
                      case PICT.OP_TX_MODE:
                          // Get the data
                          byte[] mode_buf = new byte[2];
                          pStream.readFully(mode_buf, 0, mode_buf.length);
                          if (DEBUG) {
                              System.out.println("txMode: " + mode_buf[0] + ", " + mode_buf[1]);
                          }
                          break;
  
                      case PICT.OP_SP_EXTRA:// WONDER WHAT IT IS?
                          // Get the data
                          pStream.readFully(new byte[4], 0, 4);
                          if (DEBUG) {
                              System.out.println("spExtra");
                          }
                          break;
  
                      case PICT.OP_PN_SIZE:
                          // Get the two words
                          // NOTE: This is out of order, compared to other Points
                          Dimension pnsize = new Dimension(pStream.readUnsignedShort(), pStream.readUnsignedShort());
                          if (DEBUG) {
                              System.out.println("pnsize: " + pnsize);
                          }
                          context.setPenSize(pnsize);
  
                          break;
  
                      case PICT.OP_PN_MODE:
                          // Get the data
                          int mode = pStream.readUnsignedShort();
                          if (DEBUG) {
                              System.out.println("pnMode: " + mode);
                          }
                          context.setPenMode(mode);
  
                          break;
  
                      case PICT.OP_PN_PAT:
                          context.setPenPattern(PICTUtil.readPattern(pStream, context.getForeground(), context.getBackground()));
                          if (DEBUG) {
                              System.out.println("pnPat");
                          }
                          break;
  
                      case PICT.OP_FILL_PAT:
                          fill = PICTUtil.readPattern(pStream);
                          if (DEBUG) {
                              System.out.println("fillPat");
                          }
                          break;
  
                      case PICT.OP_OV_SIZE:// OK, we use this for rounded rectangle corners
                          // Get the two words
                          int y = getYPtCoord(pStream.readUnsignedShort());
                          int x = getXPtCoord(pStream.readUnsignedShort());
  
                          ovSize.setLocation(x, y);
                          /*
                          ovSize.x *= 2;// Don't know why, but has to be multiplied by 2
                          
                          ovSize.y *= 2;
                          */
                          if (DEBUG) {
                              System.out.println("ovSize: " + ovSize);
                          }
                          break;
  
                      case PICT.OP_ORIGIN:// PROBABLY OK
                          // Get the two words
                          y = getYPtCoord(pStream.readUnsignedShort());
                          x = getXPtCoord(pStream.readUnsignedShort());
                          origin = new Point(x, y);
                          if (DEBUG) {
                              System.out.println("Origin: " + origin);
                          }
                          break;
  
                      case PICT.OP_TX_SIZE:// OK
                          // Get the text size
                          int tx_size = getYPtCoord(pStream.readUnsignedShort());
                          context.setTextSize(tx_size);
                          if (DEBUG) {
                              System.out.println("txSize: " + tx_size);
                          }
                          break;
  
                      case PICT.OP_FG_COLOR:// TO BE DONE IF POSSIBLE
                          // TODO!
                          // Get the data
                          pStream.readInt();
                          if (DEBUG) {
                              System.out.println("fgColor");
                          }
                          break;
  
                      case PICT.OP_BK_COLOR:// TO BE DONE IF POSSIBLE
                          // TODO!
                          // Get the data
                          pStream.readInt();
                          if (DEBUG) {
                              System.out.println("bgColor");
                          }
                          break;
  
                      case PICT.OP_TX_RATIO:// SEE IF WE HAVE THIS???
                          // Get the data
                          pStream.readFully(new byte[8], 0, 8);
                          if (DEBUG) {
                              System.out.println("txRatio");
                          }
                          break;
  
                      case PICT.OP_VERSION:// OK, ignored since we should already have it
                          // Get the data
                          pStream.readFully(new byte[1], 0, 1);
                          if (DEBUG) {
                              System.out.println("opVersion");
                          }
                          break;
  
                      case 0x0012: // BkPixPat
                          bg = PICTUtil.readColorPattern(pStream);
                          context.setBackgroundPattern(bg);
                          if (DEBUG) {
                              System.out.println("BkPixPat");
                          }
                          break;
                      case 0x0013: // PnPixPat
                          pen = PICTUtil.readColorPattern(pStream);
                          context.setPenPattern(pen);
                          if (DEBUG) {
                              System.out.println("PnPixPat");
                          }
                          break;
                      case 0x0014: // FillPixPat
                          fill = PICTUtil.readColorPattern(pStream);
                          context.setFillPattern(fill);
                          if (DEBUG) {
                              System.out.println("FillPixPat");
                          }
                          break;
  
                      case PICT.OP_PN_LOC_H_FRAC:// TO BE DONE???
                          // Get the data
                          pStream.readFully(new byte[2], 0, 2);
                          if (DEBUG) {
                              System.out.println("opPnLocHFrac");
                          }
                          break;
  
                      case PICT.OP_CH_EXTRA:// TO BE DONE???
                          // Get the data
                          pStream.readFully(new byte[2], 0, 2);
                          if (DEBUG) {
                              System.out.println("opChExtra");
                          }
                          break;
  
                      case PICT.OP_RGB_FG_COL:// OK
                          // Get the color
                          pStream.readFully(colorBuffer, 0, colorBuffer.length);
                          Color foreground = new Color((colorBuffer[0] & 0xFF), (colorBuffer[2] & 0xFF), (colorBuffer[4] & 0xFF));
                          if (DEBUG) {
                              System.out.println("rgbFgColor: " + foreground);
                          }
                          context.setForeground(foreground);
                          break;
  
                      case PICT.OP_RGB_BK_COL:// OK
                          // Get the color
                          pStream.readFully(colorBuffer, 0, colorBuffer.length);
                          // The color might be 16 bit per component..
                          Color background = new Color(colorBuffer[0] & 0xFF, colorBuffer[2] & 0xFF, colorBuffer[4] & 0xFF);
                          if (DEBUG) {
                              System.out.println("rgbBgColor: " + background);
                          }
                          context.setBackground(background);
                          break;
  
                      case PICT.OP_HILITE_MODE:
                          // Change color to hilite color
                          context.setPenPattern(new BitMapPattern(hilight));
                          if (DEBUG) {
                              System.out.println("opHiliteMode");
                          }
                          break;
  
                      case PICT.OP_HILITE_COLOR:// OK
                          // Get the color
                          pStream.readFully(colorBuffer, 0, colorBuffer.length);
                          // TODO: The color might be 16 bit per component..
                          hilight = new Color((colorBuffer[0] & 0xFF), (colorBuffer[2] & 0xFF), (colorBuffer[4] & 0xFF));
                          if (DEBUG) {
                              System.out.println("opHiliteColor: " + hilight);
                          }
                          break;
  
                      case PICT.OP_DEF_HILITE:// Macintosh internal, ignored?
                          // Nothing to do
                          hilight = Color.red; // TODO: My guess it's a reset, verify!
                          if (DEBUG) {
                              System.out.println("opDefHilite");
                          }
                          break;
  
                      case PICT.OP_OP_COLOR:// To be done once I know what it means
                          // TODO: Is this the mask? Scale value for RGB colors?
                          // Get the color
                          pStream.readFully(colorBuffer, 0, colorBuffer.length);
                          if (DEBUG) {
                              System.out.println("opOpColor");
                          }
                          break;
  
                      case PICT.OP_LINE:// OK, not tested
                          // Get the data (two points)
                          y = getYPtCoord(pStream.readUnsignedShort());
                          x = getXPtCoord(pStream.readUnsignedShort());
                          origin = new Point(x, y);
  
                          y = getYPtCoord(pStream.readUnsignedShort());
                          x = getXPtCoord(pStream.readUnsignedShort());
                          penPosition.setLocation(x, y);
  
                          // Move pen to new position, draw line
                          context.moveTo(origin);
                          context.lineTo(penPosition);
  
                          if (DEBUG) {
                              System.out.println("line from: " + origin + " to: " + penPosition);
                          }
                          break;
  
                      case PICT.OP_LINE_FROM:// OK, not tested
                          // Get the point
                          y = getYPtCoord(pStream.readUnsignedShort());
                          x = getXPtCoord(pStream.readUnsignedShort());
  
                          // Draw line
                          context.line(x, y);
  
                          if (DEBUG) {
                              System.out.println("lineFrom to: " + penPosition);
                          }
                          break;
  
                      case PICT.OP_SHORT_LINE:// OK
                          // Get origin and dh, dv
                          y = getYPtCoord(pStream.readUnsignedShort());
                          x = getXPtCoord(pStream.readUnsignedShort());
                          origin = new Point(x, y);
  
                          x = getXPtCoord(pStream.readByte());
                          y = getYPtCoord(pStream.readByte());
                          dh_dv = new Point(x, y);
  
                          // Move pen to new position, draw line if we have a graphics
                          context.moveTo(origin);
                          penPosition.setLocation(origin.x + dh_dv.x, origin.y + dh_dv.y);
                          context.lineTo(penPosition);
  
                          if (DEBUG) {
                              System.out.println("Short line origin: " + origin + ", dh,dv: " + dh_dv);
                          }
                          break;
  
                      case PICT.OP_SHORT_LINE_FROM:// OK
                          // Get dh, dv
                          x = getXPtCoord(pStream.readByte());
                          y = getYPtCoord(pStream.readByte());
  
                          // Draw line
                          context.line(x, y);
  
                          if (DEBUG) {
                              System.out.println("Short line from dh,dv: " + x + "," + y);
                          }
                          break;
  
                      case 0x24:
                      case 0x25:
                      case 0x26:
                      case 0x27:
                          // Apple reserved
                          dataLength = pStream.readUnsignedShort();
  
                          pStream.readFully(new byte[dataLength], 0, dataLength);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                      case PICT.OP_LONG_TEXT:// OK
                          // Get the data
                          y = getYPtCoord(pStream.readUnsignedShort());
                          x = getXPtCoord(pStream.readUnsignedShort());
                          origin = new Point(x, y);
                          penPosition = origin;
                          context.moveTo(penPosition);
                          text = PICTUtil.readPascalString(pStream);
                          context.drawString(text);
                          if (DEBUG) {
                              System.out.println("longText origin: " + penPosition + ", text:" + text);
                          }
                          break;
  
                      case PICT.OP_DH_TEXT:// OK, not tested
                          // Get dh
                          dh = getXPtCoord(pStream.readByte());
                          penPosition.translate(dh, 0);
                          context.moveTo(penPosition);
                          text = PICTUtil.readPascalString(pStream);
                          context.drawString(text);
                          if (DEBUG) {
                              System.out.println("DHText dh: " + dh + ", text:" + text);
                          }
                          break;
  
                      case PICT.OP_DV_TEXT:// OK, not tested
                          // Get dh
                          dv = getYPtCoord(pStream.readByte());
                          penPosition.translate(0, dv);
                          context.moveTo(penPosition);
                          text = PICTUtil.readPascalString(pStream);
                          context.drawString(text);
                          if (DEBUG) {
                              System.out.println("DVText dv: " + dv + ", text:" + text);
                          }
                          break;
  
                      case PICT.OP_DHDV_TEXT:// OK, not tested
                          // Get dh, dv
                          y = getYPtCoord(pStream.readByte());
                          x = getXPtCoord(pStream.readByte());
                          penPosition.translate(x, y);
                          context.moveTo(penPosition);
                          text = PICTUtil.readPascalString(pStream);
                          context.drawString(text);
                          if (DEBUG) {
                              System.out.println("DHDVText penPosition: " + penPosition + ", text:" + text);
                          }
                          break;
  
                      case PICT.OP_FONT_NAME:// OK, not tested
                          // Get data length
                          /*data_len = */
                          pStream.readShort();
  
                          // Get old font ID, ignored
                          pStream.readUnsignedShort();
  
                          // Get font name and set the new font if we have one
                          String fontName = PICTUtil.readPascalString(pStream);
                          context.setTextFont(fontName);
                          if (DEBUG) {
                              System.out.println("fontName: \"" + fontName +"\"");
                          }
                          break;
  
                      case PICT.OP_LINE_JUSTIFY:// TODO
                          // Get data
                          byte[] lineJustifyData = new byte[10];
                          pStream.readFully(lineJustifyData, 0, lineJustifyData.length);
                          if (DEBUG) {
                              System.out.println("opLineJustify");
                          }
                          break;
  
                      case PICT.OP_GLYPH_STATE:// TODO: NOT SUPPORTED IN AWT GRAPHICS YET?
                          // Get data
                          byte[] glyphState = new byte[6];
                          pStream.readFully(glyphState, 0, glyphState.length);
                          if (DEBUG) {
                              System.out.println("glyphState: " + Arrays.toString(glyphState));
                          }
                          break;
  
                      case 0x2F:
                          dataLength = pStream.readUnsignedShort();
                          pStream.readFully(new byte[dataLength], 0, dataLength);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                          //--------------------------------------------------------------------------------
                          // Rect treatments
                          //--------------------------------------------------------------------------------
                      case PICT.OP_FRAME_RECT:// OK
                      case PICT.OP_PAINT_RECT:// OK
                      case PICT.OP_ERASE_RECT:// OK, not tested
                      case PICT.OP_INVERT_RECT:// OK, not tested
                      case PICT.OP_FILL_RECT:// OK, not tested
                          // Get the frame rectangle
                          readRectangle(pStream, lastRectangle);
  
                      case PICT.OP_FRAME_SAME_RECT:// OK, not tested
                      case PICT.OP_PAINT_SAME_RECT:// OK, not tested
                      case PICT.OP_ERASE_SAME_RECT:// OK, not tested
                      case PICT.OP_INVERT_SAME_RECT:// OK, not tested
                      case PICT.OP_FILL_SAME_RECT:// OK, not tested
                          // Draw
                          switch (opCode) {
                              case PICT.OP_FRAME_RECT:
                              case PICT.OP_FRAME_SAME_RECT:
                                  context.frameRect(lastRectangle);
                                  break;
                              case PICT.OP_PAINT_RECT:
                              case PICT.OP_PAINT_SAME_RECT:
                                  context.paintRect(lastRectangle);
                                  break;
                              case PICT.OP_ERASE_RECT:
                              case PICT.OP_ERASE_SAME_RECT:
                                  context.eraseRect(lastRectangle);
                                  break;
                              case PICT.OP_INVERT_RECT:
                              case PICT.OP_INVERT_SAME_RECT:
                                  context.invertRect(lastRectangle);
                                  break;
                              case PICT.OP_FILL_RECT:
                              case PICT.OP_FILL_SAME_RECT:
                                  context.fillRect(lastRectangle, fill);
                                  break;
                          }
  
                          // Do verbose mode output
                          if (DEBUG) {
                              switch (opCode) {
                                  case PICT.OP_FRAME_RECT:
                                      System.out.println("frameRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_PAINT_RECT:
                                      System.out.println("paintRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_ERASE_RECT:
                                      System.out.println("eraseRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_INVERT_RECT:
                                      System.out.println("invertRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_FILL_RECT:
                                      System.out.println("fillRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_FRAME_SAME_RECT:
                                      System.out.println("frameSameRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_PAINT_SAME_RECT:
                                      System.out.println("paintSameRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_ERASE_SAME_RECT:
                                      System.out.println("eraseSameRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_INVERT_SAME_RECT:
                                      System.out.println("invertSameRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_FILL_SAME_RECT:
                                      System.out.println("fillSameRect: " + lastRectangle);
                                      break;
                              }
                          }
  
                          // Rect treatments finished
                          break;
  
                      case 0x003d:
                      case 0x003e:
                      case 0x003f:
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                          //--------------------------------------------------------------------------------
                          // Round Rect treatments
                          //--------------------------------------------------------------------------------
                      case PICT.OP_FRAME_R_RECT:// OK
                      case PICT.OP_PAINT_R_RECT:// OK, not tested
                      case PICT.OP_ERASE_R_RECT:// OK, not tested
                      case PICT.OP_INVERT_R_RECT:// OK, not tested
                      case PICT.OP_FILL_R_RECT:// OK, not tested
                          // Get the frame rectangle
                          readRectangle(pStream, lastRectangle);
  
                      case PICT.OP_FRAME_SAME_R_RECT:// OK, not tested
                      case PICT.OP_PAINT_SAME_R_RECT:// OK, not tested
                      case PICT.OP_ERASE_SAME_R_RECT:// OK, not tested
                      case PICT.OP_INVERT_SAME_R_RECT:// OK, not tested
                      case PICT.OP_FILL_SAME_R_RECT:// OK, not tested
                          // Draw
                          switch (opCode) {
                              case PICT.OP_FRAME_R_RECT:
                              case PICT.OP_FRAME_SAME_R_RECT:
                                  context.frameRoundRect(lastRectangle, ovSize.x, ovSize.y);
                                  break;
                              case PICT.OP_PAINT_R_RECT:
                              case PICT.OP_PAINT_SAME_R_RECT:
                                  context.paintRoundRect(lastRectangle, ovSize.x, ovSize.y);
                                  break;
                              case PICT.OP_ERASE_R_RECT:
                              case PICT.OP_ERASE_SAME_R_RECT:
                                  context.eraseRoundRect(lastRectangle, ovSize.x, ovSize.y);
                                  break;
                              case PICT.OP_INVERT_R_RECT:
                              case PICT.OP_INVERT_SAME_R_RECT:
                                  context.invertRoundRect(lastRectangle, ovSize.x, ovSize.y);
                                  break;
                              case PICT.OP_FILL_R_RECT:
                              case PICT.OP_FILL_SAME_R_RECT:
                                  context.fillRoundRect(lastRectangle, ovSize.x, ovSize.y, fill);
                                  break;
                          }
  
                          // Do verbose mode output
                          if (DEBUG) {
                              switch (opCode) {
                                  case PICT.OP_FRAME_R_RECT:
                                      System.out.println("frameRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_PAINT_R_RECT:
                                      System.out.println("paintRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_ERASE_R_RECT:
                                      System.out.println("eraseRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_INVERT_R_RECT:
                                      System.out.println("invertRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_FILL_R_RECT:
                                      System.out.println("fillRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_FRAME_SAME_R_RECT:
                                      System.out.println("frameSameRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_PAINT_SAME_R_RECT:
                                      System.out.println("paintSameRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_ERASE_SAME_R_RECT:
                                      System.out.println("eraseSameRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_INVERT_SAME_R_RECT:
                                      System.out.println("invertSameRRect: " + lastRectangle);
                                      break;
                                  case PICT.OP_FILL_SAME_R_RECT:
                                      System.out.println("fillSameRRect: " + lastRectangle);
                                      break;
                              }
                          }
  
                          // RoundRect treatments finished
                          break;
  
                          //--------------------------------------------------------------------------------
                          // Oval treatments
                          //--------------------------------------------------------------------------------
                      case PICT.OP_FRAME_OVAL:// OK
                      case PICT.OP_PAINT_OVAL:// OK, not tested
                      case PICT.OP_ERASE_OVAL:// OK, not tested
                      case PICT.OP_INVERT_OVAL:// OK, not tested
                      case PICT.OP_FILL_OVAL:// OK, not tested
                          // Get the frame rectangle
                          readRectangle(pStream, lastRectangle);
                      case PICT.OP_FRAME_SAME_OVAL:// OK, not tested
                      case PICT.OP_PAINT_SAME_OVAL:// OK, not tested
                      case PICT.OP_ERASE_SAME_OVAL:// OK, not tested
                      case PICT.OP_INVERT_SAME_OVAL:// OK, not tested
                      case PICT.OP_FILL_SAME_OVAL:// OK, not tested
                          // Draw
                          switch (opCode) {
                              case PICT.OP_FRAME_OVAL:
                              case PICT.OP_FRAME_SAME_OVAL:
                                  context.frameOval(lastRectangle);
                                  break;
                              case PICT.OP_PAINT_OVAL:
                              case PICT.OP_PAINT_SAME_OVAL:
                                  context.paintOval(lastRectangle);
                                  break;
                              case PICT.OP_ERASE_OVAL:
                              case PICT.OP_ERASE_SAME_OVAL:
                                  context.eraseOval(lastRectangle);
                                  break;
                              case PICT.OP_INVERT_OVAL:
                              case PICT.OP_INVERT_SAME_OVAL:
                                  context.invertOval(lastRectangle);
                                  break;
                              case PICT.OP_FILL_OVAL:
                              case PICT.OP_FILL_SAME_OVAL:
                                  context.fillOval(lastRectangle, fill);
                                  break;
                          }
  
                          // Do verbose mode output
                          if (DEBUG) {
                              switch (opCode) {
                                  case PICT.OP_FRAME_OVAL:
                                      System.out.println("frameOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_PAINT_OVAL:
                                      System.out.println("paintOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_ERASE_OVAL:
                                      System.out.println("eraseOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_INVERT_OVAL:
                                      System.out.println("invertOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_FILL_OVAL:
                                      System.out.println("fillOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_FRAME_SAME_OVAL:
                                      System.out.println("frameSameOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_PAINT_SAME_OVAL:
                                      System.out.println("paintSameOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_ERASE_SAME_OVAL:
                                      System.out.println("eraseSameOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_INVERT_SAME_OVAL:
                                      System.out.println("invertSameOval: " + lastRectangle);
                                      break;
                                  case PICT.OP_FILL_SAME_OVAL:
                                      System.out.println("fillSameOval: " + lastRectangle);
                                      break;
                              }
                          }
  
                          // Oval treatments finished
                          break;
  
                      case 0x35:
                      case 0x36:
                      case 0x37:
                      case 0x45:
                      case 0x46:
                      case 0x47:
                      case 0x55:
                      case 0x56:
                      case 0x57:
                          pStream.readFully(new byte[8], 0, 8);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                          //--------------------------------------------------------------------------------
                          // Arc treatments
                          //--------------------------------------------------------------------------------
                      case PICT.OP_FRAME_ARC:// OK, not tested
                      case PICT.OP_PAINT_ARC:// OK, not tested
                      case PICT.OP_ERASE_ARC:// OK, not tested
                      case PICT.OP_INVERT_ARC:// OK, not tested
                      case PICT.OP_FILL_ARC:// OK, not tested
                          // Get the frame rectangle
                          readRectangle(pStream, lastRectangle);
                      case PICT.OP_FRAME_SAME_ARC:// OK, not tested
                      case PICT.OP_PAINT_SAME_ARC:// OK, not tested
                      case PICT.OP_ERASE_SAME_ARC:// OK, not tested
                      case PICT.OP_INVERT_SAME_ARC:// OK, not tested
                      case PICT.OP_FILL_SAME_ARC:// OK, not tested
                          // NOTE: These are inlcuded even if SAME
                          // Get start and end angles
                          //x = getXPtCoord(pStream.readUnsignedShort());
                          //y = getYPtCoord(pStream.readUnsignedShort());
                          x = pStream.readUnsignedShort();
                          y = pStream.readUnsignedShort();
                          arcAngles.setLocation(x, y);
  
                          // Draw
                          switch (opCode) {
                              case PICT.OP_FRAME_ARC:
                              case PICT.OP_FRAME_SAME_ARC:
                                  context.frameArc(lastRectangle, arcAngles.x, arcAngles.y);
                                  break;
                              case PICT.OP_PAINT_ARC:
                              case PICT.OP_PAINT_SAME_ARC:
                                  context.paintArc(lastRectangle, arcAngles.x, arcAngles.y);
                                  break;
                              case PICT.OP_ERASE_ARC:
                              case PICT.OP_ERASE_SAME_ARC:
                                  context.eraseArc(lastRectangle, arcAngles.x, arcAngles.y);
                                  break;
                              case PICT.OP_INVERT_ARC:
                              case PICT.OP_INVERT_SAME_ARC:
                                  context.invertArc(lastRectangle, arcAngles.x, arcAngles.y);
                                  break;
                              case PICT.OP_FILL_ARC:
                              case PICT.OP_FILL_SAME_ARC:
                                  context.fillArc(lastRectangle, arcAngles.x, arcAngles.y, fill);
                                  break;
                          }
  
                          // Do verbose mode output
                          if (DEBUG) {
                              switch (opCode) {
                                  case PICT.OP_FRAME_ARC:
                                      System.out.println("frameArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_PAINT_ARC:
                                      System.out.println("paintArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_ERASE_ARC:
                                      System.out.println("eraseArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_INVERT_ARC:
                                      System.out.println("invertArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_FILL_ARC:
                                      System.out.println("fillArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_FRAME_SAME_ARC:
                                      System.out.println("frameSameArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_PAINT_SAME_ARC:
                                      System.out.println("paintSameArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_ERASE_SAME_ARC:
                                      System.out.println("eraseSameArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_INVERT_SAME_ARC:
                                      System.out.println("invertSameArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                                  case PICT.OP_FILL_SAME_ARC:
                                      System.out.println("fillSameArc: " + lastRectangle + ", angles:" + arcAngles);
                                      break;
                              }
                          }
  
                          // Arc treatments finished
                          break;
  
                      case 0x65:
                      case 0x66:
                      case 0x67:
                          pStream.readFully(new byte[12], 0, 12);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
                      case 0x6d:
                      case 0x6e:
                      case 0x6f:
                          pStream.readFully(new byte[4], 0, 4);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                          //--------------------------------------------------------------------------------
                          // Polygon treatments
                          //--------------------------------------------------------------------------------
                      case PICT.OP_FRAME_POLY:// OK
                      case PICT.OP_PAINT_POLY:// OK
                      case PICT.OP_ERASE_POLY:// OK, not tested
                      case PICT.OP_INVERT_POLY:// OK, not tested
                      case PICT.OP_FILL_POLY:// OK, not tested
                          // Read the polygon
                          polygon = readPoly(pStream, bounds);
  
                      case PICT.OP_FRAME_SAME_POLY:// OK, not tested
                      case PICT.OP_PAINT_SAME_POLY:// OK, not tested
                      case PICT.OP_ERASE_SAME_POLY:// OK, not tested
                      case PICT.OP_INVERT_SAME_POLY:// OK, not tested
                      case PICT.OP_FILL_SAME_POLY:// OK, not tested
  
                          // Draw
                          switch (opCode) {
                              case PICT.OP_FRAME_POLY:
                              case PICT.OP_FRAME_SAME_POLY:
                                  context.framePoly(polygon);
                                  break;
                              case PICT.OP_PAINT_POLY:
                              case PICT.OP_PAINT_SAME_POLY:
                                  context.paintPoly(polygon);
                                  break;
                              case PICT.OP_ERASE_POLY:
                              case PICT.OP_ERASE_SAME_POLY:
                                  context.erasePoly(polygon);
                                  break;
                              case PICT.OP_INVERT_POLY:
                              case PICT.OP_INVERT_SAME_POLY:
                                  context.invertPoly(polygon);
                                  break;
                              case PICT.OP_FILL_POLY:
                              case PICT.OP_FILL_SAME_POLY:
                                  context.fillPoly(polygon, fill);
                                  break;
                          }
  
                          // Do verbose mode output
                          if (DEBUG) {
                              switch (opCode) {
                                  case PICT.OP_FRAME_POLY:
                                      verbosePolyCmd("framePoly", bounds, polygon);
                                      break;
                                  case PICT.OP_PAINT_POLY:
                                      verbosePolyCmd("paintPoly", bounds, polygon);
                                      break;
                                  case PICT.OP_ERASE_POLY:
                                      verbosePolyCmd("erasePoly", bounds, polygon);
                                      break;
                                  case PICT.OP_INVERT_POLY:
                                      verbosePolyCmd("invertPoly", bounds, polygon);
                                      break;
                                  case PICT.OP_FILL_POLY:
                                      verbosePolyCmd("fillPoly", bounds, polygon);
                                      break;
                                  case PICT.OP_FRAME_SAME_POLY:
                                      verbosePolyCmd("frameSamePoly", bounds, polygon);
                                      break;
                                  case PICT.OP_PAINT_SAME_POLY:
                                      verbosePolyCmd("paintSamePoly", bounds, polygon);
                                      break;
                                  case PICT.OP_ERASE_SAME_POLY:
                                      verbosePolyCmd("eraseSamePoly", bounds, polygon);
                                      break;
                                  case PICT.OP_INVERT_SAME_POLY:
                                      verbosePolyCmd("invertSamePoly", bounds, polygon);
                                      break;
                                  case PICT.OP_FILL_SAME_POLY:
                                      verbosePolyCmd("fillSamePoly", bounds, polygon);
                                      break;
                              }
                          }
  
                          // Polygon treatments finished
                          break;
  
                      case 0x7d:
                      case 0x7e:
                      case 0x7f:
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                      case 0x75:
                      case 0x76:
                      case 0x77:
                          // Read the polygon
                          polygon = readPoly(pStream, bounds);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                          //--------------------------------------------------------------------------------
                          // Region treatments
                          //--------------------------------------------------------------------------------
                      case PICT.OP_FRAME_RGN:// OK, not tested
                      case PICT.OP_PAINT_RGN:// OK, not tested
                      case PICT.OP_ERASE_RGN:// OK, not tested
                      case PICT.OP_INVERT_RGN:// OK, not tested
                      case PICT.OP_FILL_RGN:// OK, not tested
                          // Read the region
                          region = readRegion(pStream, bounds);
  
                      case PICT.OP_FRAME_SAME_RGN:// OK, not tested
                      case PICT.OP_PAINT_SAME_RGN:// OK, not tested
                      case PICT.OP_ERASE_SAME_RGN:// OK, not tested
                      case PICT.OP_INVERT_SAME_RGN:// OK, not tested
                      case PICT.OP_FILL_SAME_RGN:// OK, not tested
                          // Draw
                          if (region != null && !region.getBounds().isEmpty()) {
                              switch (opCode) {
                                  case PICT.OP_FRAME_RGN:
                                  case PICT.OP_FRAME_SAME_RGN:
                                      context.frameRegion(region);
                                      break;
                                  case PICT.OP_PAINT_RGN:
                                  case PICT.OP_PAINT_SAME_RGN:
                                      context.paintRegion(region);
                                      break;
                                  case PICT.OP_ERASE_RGN:
                                  case PICT.OP_ERASE_SAME_RGN:
                                      context.eraseRegion(region);
                                      break;
                                  case PICT.OP_INVERT_RGN:
                                  case PICT.OP_INVERT_SAME_RGN:
                                      context.invertRegion(region);
                                      break;
                                  case PICT.OP_FILL_RGN:
                                  case PICT.OP_FILL_SAME_RGN:
                                      context.fillRegion(region, fill);
                                      break;
                              }
                          }
  
                          // Do verbose mode output
                          if (DEBUG) {
                              switch (opCode) {
                                  case PICT.OP_FRAME_RGN:
                                      verboseRegionCmd("frameRgn", bounds, region);
                                      break;
                                  case PICT.OP_PAINT_RGN:
                                      verboseRegionCmd("paintRgn", bounds, region);
                                      break;
                                  case PICT.OP_ERASE_RGN:
                                      verboseRegionCmd("eraseRgn", bounds, region);
                                      break;
                                  case PICT.OP_INVERT_RGN:
                                      verboseRegionCmd("invertRgn", bounds, region);
                                      break;
                                  case PICT.OP_FILL_RGN:
                                      verboseRegionCmd("fillRgn", bounds, region);
                                      break;
                                  case PICT.OP_FRAME_SAME_RGN:
                                      verboseRegionCmd("frameSameRgn", bounds, region);
                                      break;
                                  case PICT.OP_PAINT_SAME_RGN:
                                      verboseRegionCmd("paintSameRgn", bounds, region);
                                      break;
                                  case PICT.OP_ERASE_SAME_RGN:
                                      verboseRegionCmd("eraseSameRgn", bounds, region);
                                      break;
                                  case PICT.OP_INVERT_SAME_RGN:
                                      verboseRegionCmd("invertSameRgn", bounds, region);
                                      break;
                                  case PICT.OP_FILL_SAME_RGN:
                                      verboseRegionCmd("fillSameRgn", bounds, region);
                                      break;
                              }
                          }
  
                          // Region treatments finished
                          break;
  
                      case 0x85:
                      case 0x86:
                      case 0x87:
                          // Read the region
                          region = readRegion(pStream, bounds);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                      case PICT.OP_BITS_RECT:
                          // [4] Four opcodes ($0090, $0091, $0098, $0099) are modifications of version 1 opcodes.
                          // The first word following the opcode is rowBytes. If the high bit of rowBytes is set,
                          // then it is a pixel map containing multiple bits per pixel; if it is not set, it is a
                          // bitmap containing 1 bit per pixel.
                          // In general, the difference between version 2 and version 1 formats is that the pixel
                          // map replaces the bitmap, a color table has been added, and pixData replaces bitData.
                          // [5] For opcodes $0090 (BitsRect) and $0091 (BitsRgn), the data is unpacked. These
                          // opcodes can be used only when rowBytes is less than 8.
                          readOpBits(pStream, false);
                          break;
  
                      case PICT.OP_BITS_RGN:
                          readOpBits(pStream, true);
  
                          break;
  
                      case 0x92:
                      case 0x93:
                      case 0x94:
                      case 0x95:
                      case 0x96:
                      case 0x97:
                          dataLength = pStream.readUnsignedShort();
                          pStream.readFully(new byte[dataLength], 0, dataLength);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x - length: %d", PICT.APPLE_USE_RESERVED_FIELD, opCode, dataLength));
                          }
                          break;
  
                      case PICT.OP_PACK_BITS_RECT:
                          readOpPackBits(pStream, false, pixmapCount++);
                          break;
  
                      case PICT.OP_PACK_BITS_RGN:
                          readOpPackBits(pStream, true, pixmapCount++);
                          break;
  
                      case PICT.OP_DIRECT_BITS_RECT:
                          readOpDirectBits(pStream, false, pixmapCount++);
                          break;
  
                      case PICT.OP_DIRECT_BITS_RGN:
                          readOpDirectBits(pStream, true, pixmapCount++);
                          break;
  
                      case 0x9C:
                      case 0x9D:
                      case 0x9E:
                      case 0x9F:
                          // TODO: Move to special Apple Reserved handling?
                          dataLength = pStream.readUnsignedShort();
                          pStream.readFully(new byte[dataLength], 0, dataLength);
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x", PICT.APPLE_USE_RESERVED_FIELD, opCode));
                          }
                          break;
  
                      case PICT.OP_SHORT_COMMENT:// NOTHING TO DO, JUST JUMP OVER
                          byte[] shortComment = new byte[2];
                          pStream.readFully(shortComment, 0, 2);
                          if (DEBUG) {
                              System.out.println("Short comment: " + Arrays.toString(shortComment));
                          }
                          break;
  
                      case PICT.OP_LONG_COMMENT:// NOTHING TO DO, JUST JUMP OVER
                          /*byte[] longComment =*/ readLongComment(pStream);
                          // TODO: Don't just skip...
                          // https://developer.apple.com/legacy/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_B.pdf
                          // Long comments can be used for PhotoShop IRBs (kind 498) or ICC profiles (224) and other meta data...
  //                        if (DEBUG) {
  //                            System.out.println("Long comment: " + Arrays.toString(longComment));
  //                        }
                          break;
  
                      case PICT.OP_END_OF_PICTURE:// OK
                          break;
  
                      case PICT.OP_COMPRESSED_QUICKTIME:
                          // $8200: CompressedQuickTime Data length (Long), data (private to QuickTime) 4 + data length
                          readCompressedQT(pStream);
  
                          break;
  
                      case PICT.OP_UNCOMPRESSED_QUICKTIME:// JUST JUMP OVER
                          // $8201: UncompressedQuickTime Data length (Long), data (private to QuickTime) 4 + data length
                          // TODO: Read this as well, need test data
                          dataLength = pStream.readInt();
                          if (DEBUG) {
                              System.out.println(String.format("unCompressedQuickTime, length %d", dataLength));
                          }
                          pStream.readFully(new byte[dataLength], 0, dataLength);
                          break;
  
                      default:
                          // See: http://developer.apple.com/DOCUMENTATION/mac/QuickDraw/QuickDraw-461.html
                          if (opCode >= 0x00a2 && opCode <= 0x00af) {
                              dataLength = pStream.readUnsignedShort();
                          }
                          else if (opCode >= 0x00b0 && opCode <= 0x00cf) {
                              // Zero-length
                              dataLength = 0;
                          }
                          else if (opCode >= 0x00d0 && opCode <= 0x00fe) {
                              dataLength = pStream.readInt();
                          }
                          else if (opCode >= 0x0100 && opCode <= 0x7fff) {
                              // For opcodes $0100-$7FFF, the amount of data for
                              // opcode $nnXX = 2 times nn bytes.
                              dataLength = (opCode & 0xff00) >> 7;
                          }
                          else if (opCode >= 0x8000 && opCode <= 0x80ff) {
                              // Zero-length
                              dataLength = 0;
                          }
                          else if (opCode >= 0x8100 && opCode <= 0x81ff) {
                              dataLength = pStream.readInt();
                          }
                          else if (opCode == 0xffff) {
                              dataLength = pStream.readInt();
                          }
                          else {
                              throw new IIOException(String.format("Found unknown opcode: 0x%04x", opCode));
                          }
  
                          if (DEBUG) {
                              System.out.println(String.format("%s: 0x%04x - length: %s", PICT.APPLE_USE_RESERVED_FIELD, opCode, dataLength));
                          }
  
                          if (dataLength != 0) {
                              pStream.readFully(new byte[dataLength], 0, dataLength);
                          }
                  }
              }
              while (opCode != PICT.OP_END_OF_PICTURE);
          }
          catch (IIOException e) {
              throw e;
          }
          catch (EOFException e) {
              String pos;
              try {
                  pos = String.format("position %d", imageInput.getStreamPosition());
              }
              catch (IOException ignore) {
                  pos = "unknown position";
              }
  
              throw new IIOException(String.format("Error in PICT format: Unexpected end of File at %s", pos), e);
          }
          catch (IOException e) {
              throw new IIOException(String.format("Error in PICT format: %s", e.getMessage()), e);
          }
      }