gt:             int dataLength = WZTool.readValue(slea);
context: package net.sf.odinms.provider.wz;
  
  import java.awt.Point;
  import java.io.DataOutputStream;
  import java.io.File;
  import java.io.IOException;
  import java.io.OutputStream;
  import java.io.RandomAccessFile;
  
  import net.sf.odinms.tools.data.input.GenericSeekableLittleEndianAccessor;
  import net.sf.odinms.tools.data.input.RandomAccessByteStream;
  import net.sf.odinms.tools.data.input.SeekableLittleEndianAccessor;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  public class WZIMGFile {
  
      private Logger log = LoggerFactory.getLogger(WZIMGFile.class);
      private WZFileEntry file;
      private WZIMGEntry root;
      private boolean provideImages;
      @SuppressWarnings("unused")
      private boolean modernImg;
  
      public WZIMGFile(File wzfile, WZFileEntry file, boolean provideImages, boolean modernImg) throws IOException {
          RandomAccessFile raf = new RandomAccessFile(wzfile, "r");
          SeekableLittleEndianAccessor slea = new GenericSeekableLittleEndianAccessor(new RandomAccessByteStream(raf));
          slea.seek(file.getOffset());
          this.file = file;
          this.provideImages = provideImages;
          root = new WZIMGEntry(file.getParent());
          root.setName(file.getName());
          root.setType(MapleDataType.EXTENDED);
          // dumpImg(new FileOutputStream(file.getName()), slea);
          this.modernImg = modernImg;
          parseExtended(root, slea, 0);
          root.finish();
          raf.close();
      }
  
      protected void dumpImg(OutputStream out, SeekableLittleEndianAccessor slea) throws IOException {
          DataOutputStream os = new DataOutputStream(out);
          long oldPos = slea.getPosition();
          slea.seek(file.getOffset());
          for (int x = 0; x < file.getSize(); x++) {
              os.write(slea.readByte());
          }
          slea.seek(oldPos);
      }
  
      public WZIMGEntry getRoot() {
          return root;
      }
  
      private void parse(WZIMGEntry entry, SeekableLittleEndianAccessor slea) {
          byte marker = slea.readByte();
          switch (marker) {
              case 0: {
                  String name = WZTool.readDecodedString(slea);
                  entry.setName(name);
                  break;
              }
              case 1: {
                  String name = WZTool.readDecodedStringAtOffsetAndReset(slea, file.getOffset() + slea.readInt());
                  entry.setName(name);
                  break;
              }
              default:
                  log.error("Unknown Image identifier: {} at offset {}", marker, (slea.getPosition() - file.getOffset()));
          }
  
          marker = slea.readByte();
  
          switch (marker) {
              case 0:
                  entry.setType(MapleDataType.IMG_0x00);
                  break;
              case 2:
              case 11: //??? no idea, since 0.49
                  entry.setType(MapleDataType.SHORT);
                  entry.setData(Short.valueOf(slea.readShort()));
                  break;
              case 3:
                  entry.setType(MapleDataType.INT);
                  entry.setData(Integer.valueOf(WZTool.readValue(slea)));
                  break;
              case 4:
                  entry.setType(MapleDataType.FLOAT);
                  entry.setData(Float.valueOf(WZTool.readFloatValue(slea)));
                  break;
              case 5:
                  entry.setType(MapleDataType.DOUBLE);
                  entry.setData(Double.valueOf(slea.readDouble()));
                  break;
              case 8:
                  entry.setType(MapleDataType.STRING);
                  byte iMarker = slea.readByte();
                  if (iMarker == 0) {
                      // String pathToData = MapleDataTool.getFullDataPath(entry);
                      entry.setData(WZTool.readDecodedString(slea));
                  } else if (iMarker == 1) {
                      entry.setData(WZTool.readDecodedStringAtOffsetAndReset(slea, slea.readInt() + file.getOffset()));
                  } else {
                      log.error("Unknown String type {}", iMarker);
                  }
                  break;
              case 9:
                  entry.setType(MapleDataType.EXTENDED);
                  long endOfExtendedBlock = slea.readInt();
                  endOfExtendedBlock += slea.getPosition();
                  parseExtended(entry, slea, endOfExtendedBlock);
                  break;
              default:
                  log.error("Unknown Image type {}", marker);
          }
      }
  
      private void parseExtended(WZIMGEntry entry, SeekableLittleEndianAccessor slea, long endOfExtendedBlock) {
          byte marker = slea.readByte();
  
          String type;
          switch (marker) {
              case 0x73:
                  type = WZTool.readDecodedString(slea);
                  break;
              case 0x1B:
                  type = WZTool.readDecodedStringAtOffsetAndReset(slea, file.getOffset() + slea.readInt());
                  break;
              default:
                  throw new RuntimeException("Unknown extended image identifier: " + marker + " at offset " +
                          (slea.getPosition() - file.getOffset()));
          }
  
          /*
           * "Shape2D#Vector2D"
           * "Shape2D#Convex2D"
           * "Property"
           * "Sound_DX8"
           * "Canvas"
           * "UOL"
           */
          if (type.equals("Property")) {
              entry.setType(MapleDataType.PROPERTY);
              slea.readByte();
              slea.readByte();
              int children = WZTool.readValue(slea);
              for (int i = 0; i < children; i++) {
                  WZIMGEntry cEntry = new WZIMGEntry(entry);
                  parse(cEntry, slea);
                  cEntry.finish();
                  entry.addChild(cEntry);
              }
          } else if (type.equals("Canvas")) {
              entry.setType(MapleDataType.CANVAS);
              slea.readByte();
              marker = slea.readByte();
              if (marker == 0) {
                  // do nothing
              } else if (marker == 1) {
                  slea.readByte();
                  slea.readByte();
                  int children = WZTool.readValue(slea);
                  for (int i = 0; i < children; i++) {
                      WZIMGEntry child = new WZIMGEntry(entry);
                      parse(child, slea);
                      child.finish();
                      entry.addChild(child);
                  }
              } else {
                  log.warn("Canvas marker != 1 ({})", marker);
              }
              int width = WZTool.readValue(slea);
              int height = WZTool.readValue(slea);
              int format = WZTool.readValue(slea);
              int format2 = slea.readByte();
              slea.readInt();
              int dataLength = slea.readInt() - 1;
              slea.readByte();
  
              if (provideImages) {
                  byte[] pngdata = slea.read(dataLength);
                  entry.setData(new PNGMapleCanvas(width, height, dataLength, format + format2, pngdata));
              } else {
                  entry.setData(new PNGMapleCanvas(width, height, dataLength, format + format2, null));
                  slea.skip(dataLength);
              }
          } else if (type.equals("Shape2D#Vector2D")) {
              entry.setType(MapleDataType.VECTOR);
              int x = WZTool.readValue(slea);
              int y = WZTool.readValue(slea);
              entry.setData(new Point(x, y));
          } else if (type.equals("Shape2D#Convex2D")) {
              int children = WZTool.readValue(slea);
              for (int i = 0; i < children; i++) {
                  WZIMGEntry cEntry = new WZIMGEntry(entry);
                  parseExtended(cEntry, slea, 0);
                  cEntry.finish();
                  entry.addChild(cEntry);
              }
          } else if (type.equals("Sound_DX8")) {
              entry.setType(MapleDataType.SOUND);
              slea.readByte();
  