cdm/src/main/java/ucar/nc2/iosp/nowrad/NOWRadiosp.java
public Object readOneScanData(ByteBuffer bos, NOWRadheader.Vinfo vinfo, String vName)
          throws IOException, InvalidRangeException {
    int doff = (int) vinfo.hoff;
    int npixel = vinfo.yt * vinfo.xt;
    byte[] rdata = null;
    byte[] ldata = new byte[vinfo.xt];
    byte[] pdata = new byte[npixel];
    byte[] b2 = new byte[2];

    bos.position(doff);

    // begining of image data
    if ((DataType.unsignedByteToShort(bos.get()) != 0xF0) || (bos.get() != 0x0C)) {
      return null;
    }

    int ecode;
    int color;
    int datapos;
    int offset = 0;
    int roffset = 0;
    boolean newline = true;
    int linenum = 0;

    while (true) {

      // line number
      if (newline) {
        bos.get(b2);
        linenum = (DataType.unsignedByteToShort(b2[1]) << 8) + DataType.unsignedByteToShort(b2[0]);

        // System.out.println("Line Number = " + linenum);
      }

      // int linenum = bytesToInt(b2[0], b2[1], true);
      // System.out.println("Line Number = " + linenum);
      // if(linenum == 1225)
      //   System.out.println(" HHHHH");
      short b = DataType.unsignedByteToShort(bos.get());

      color = b & 0xF;
      ecode = b >> 4;
      datapos = bos.position();

      int datarun;

      if (ecode == 0xF) {
        byte bb1 = bos.get(datapos - 2);
        byte bb2 = bos.get(datapos);

        if ((color == 0x0) && (bb1 == 0x00) && (bb2 == 0x00)) {
          datapos += 1;
        }

        bos.position(datapos);
        datarun = 0;
      } else if (ecode == 0xE) {
        byte b0 = bos.get(datapos);

        datarun = DataType.unsignedByteToShort(b0) + 1;
        datapos += 1;
        bos.position(datapos);
      } else if (ecode == 0xD) {
        b2[0] = bos.get(datapos);
        b2[1] = bos.get(datapos + 1);
        datarun = (DataType.unsignedByteToShort(b2[1]) << 8) + DataType.unsignedByteToShort(b2[0]) + 1;
        datapos += 2;
        bos.position(datapos);
      } else {
        datarun = ecode + 1;
      }

      // move the unpacked data in the data line
      rdata = new byte[datarun];

      for (int i = 0; i < datarun; i++) {
        rdata[i] = (byte) color;
      }

      System.arraycopy(rdata, 0, ldata, roffset, datarun);
      roffset = roffset + datarun;

      // System.out.println("run ecode = " + ecode + " and data run " + datarun + " and totalrun " + roffset);
      // check to see if the beginning of the next line or at the end of the file
      short c0 = DataType.unsignedByteToShort(bos.get());

      if (c0 == 0x00) {
        short c1 = DataType.unsignedByteToShort(bos.get());
        short c2 = DataType.unsignedByteToShort(bos.get());

        // System.out.println("c1 and c2 " + c1 + " " + c2);

        if ((c0 == 0x00) && (c1 == 0xF0) && (c2 == 0x0C)) {
          // beginning of next line
          //  System.out.println("linenum   " + linenum + "   and this line total " + roffset);
          //  if (roffset != 3661) {
          //      System.out.println("ERROR missing data, this line total only " + roffset);
          //  }
          System.arraycopy(ldata, 0, pdata, offset, roffset);
          offset = offset + vinfo.xt;
          roffset = 0;
          newline = true;
          ldata = new byte[vinfo.xt];
        } else if ((c1 == 0xF0) && (c2 == 0x02)) {
          // end of the file
          break;
        } else {
          datapos = bos.position() - 3;
          bos.position(datapos);
          newline = false;
        }
      } else {
        newline = false;
        datapos = bos.position();
        bos.position(datapos - 1);
      }
    }

    return pdata;
  }
public Object readOneScanData(ByteBuffer bos, NOWRadheader.Vinfo vinfo, String vName)
          throws IOException, InvalidRangeException {
    int doff = (int) vinfo.hoff;
    int npixel = vinfo.yt * vinfo.xt;
    byte[] rdata = null;
    byte[] ldata = new byte[vinfo.xt];
    byte[] pdata = new byte[npixel];
    byte[] b2 = new byte[2];

    bos.position(doff);

    // begining of image data
    if ((DataType.unsignedByteToShort(bos.get()) != 0xF0) || (bos.get() != 0x0C)) {
      return null;
    }

    int ecode;
    int color;
    int datapos;
    int offset = 0;
    int roffset = 0;
    boolean newline = true;
    int linenum = 0;

    while (true) {

      // line number
      if (newline) {
        bos.get(b2);
        linenum = (DataType.unsignedByteToShort(b2[1]) << 8) + DataType.unsignedByteToShort(b2[0]);

        // System.out.println("Line Number = " + linenum);
      }

      // int linenum = bytesToInt(b2[0], b2[1], true);
      // System.out.println("Line Number = " + linenum);
      // if(linenum == 1225)
      //   System.out.println(" HHHHH");
      short b = DataType.unsignedByteToShort(bos.get());

      color = b & 0xF;
      ecode = b >> 4;
      datapos = bos.position();

      int datarun;

      if (ecode == 0xF) {
        byte bb1 = bos.get(datapos - 2);
        byte bb2 = bos.get(datapos);

        if ((color == 0x0) && (bb1 == 0x00) && (bb2 == 0x00)) {
          datapos += 1;
        }

        bos.position(datapos);
        datarun = 0;
      } else if (ecode == 0xE) {
        byte b0 = bos.get(datapos);

        datarun = DataType.unsignedByteToShort(b0) + 1;
        datapos += 1;
        bos.position(datapos);
      } else if (ecode == 0xD) {
        b2[0] = bos.get(datapos);
        b2[1] = bos.get(datapos + 1);
        datarun = (DataType.unsignedByteToShort(b2[1]) << 8) + DataType.unsignedByteToShort(b2[0]) + 1;
        datapos += 2;
        bos.position(datapos);
      } else {
        datarun = ecode + 1;
      }

      // move the unpacked data in the data line
      rdata = new byte[datarun];

      for (int i = 0; i < datarun; i++) {
        rdata[i] = (byte) color;
      }

      System.arraycopy(rdata, 0, ldata, roffset, datarun);
      roffset = roffset + datarun;

      // System.out.println("run ecode = " + ecode + " and data run " + datarun + " and totalrun " + roffset);
      // check to see if the beginning of the next line or at the end of the file
      short c0 = DataType.unsignedByteToShort(bos.get());

      if (c0 == 0x00) {
        short c1 = DataType.unsignedByteToShort(bos.get());
        short c2 = DataType.unsignedByteToShort(bos.get());

        // System.out.println("c1 and c2 " + c1 + " " + c2);

        if ((c0 == 0x00) && (c1 == 0xF0) && (c2 == 0x0C)) {
          // beginning of next line
          //  System.out.println("linenum   " + linenum + "   and this line total " + roffset);
          //  if (roffset != 3661) {
          //      System.out.println("ERROR missing data, this line total only " + roffset);
          //  }
          System.arraycopy(ldata, 0, pdata, offset, roffset);
          offset = offset + vinfo.xt;
          roffset = 0;
          newline = true;
          ldata = new byte[vinfo.xt];
        } else if ((c1 == 0xF0) && (c2 == 0x02)) {
          // end of the file
          break;
        } else {
          datapos = bos.position() - 3;
          bos.position(datapos);
          newline = false;
        }
      } else {
        newline = false;
        datapos = bos.position();
        bos.position(datapos - 1);
      }
    }

    return pdata;
  }
all the work is here, so can be called recursively