Changeset 4076


Ignore:
Timestamp:
05/29/08 16:56:58 (12 years ago)
Author:
melissa
Message:
  • Removed a bunch of duplicate code from PictReader
  • Fixed OpenlabReader to handle openlab/stefan/270508. Note that this file's images still look wrong (since the file is all kinds of corrupt), but at least all of the images are detected now.
Location:
trunk/loci/formats/in
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/in/OpenlabReader.java

    r4072 r4076  
    171171    else { 
    172172      // PICT plane 
    173       in.read(b); 
     173      b = new byte[b.length + 512]; 
     174      in.read(b, 512, b.length - 512); 
    174175      Exception exc = null; 
    175176      try { 
    176         BufferedImage img = pict.open(b).getSubimage(x, y, w, h); 
    177         byte[][] pix = ImageTools.getPixelBytes(img, core.littleEndian[series]); 
    178         for (int i=0; i<core.sizeC[series]; i++) { 
    179           System.arraycopy(pix[i], 0, buf, i*pix[i].length, pix[i].length); 
    180         } 
     177        Location.mapFile("OPENLAB_PICT", new RABytes(b)); 
     178        pict.setId("OPENLAB_PICT"); 
     179        buf = pict.openBytes(0, x, y, w, h); 
     180        pict.close(); 
    181181      } 
    182182      catch (FormatException e) { exc = e; } 
     
    184184 
    185185      if (exc != null) { 
     186        if (debug) LogTools.trace(exc); 
    186187        in.seek(planes[planeOffsets[series][no]].planeOffset - 298); 
    187188 
     
    194195          new byte[getSizeX() * getSizeY() * bpp * getRGBChannelCount()]; 
    195196 
    196         while (expectedBlock != totalBlocks) { 
    197           while (in.readLong() != 0x4956454164627071L) { 
     197        while (expectedBlock != totalBlocks && 
     198          in.getFilePointer() + 32 < in.length()) 
     199        { 
     200          while (in.readLong() != 0x4956454164627071L && 
     201            in.getFilePointer() < in.length()) 
     202          { 
    198203            in.seek(in.getFilePointer() - 7); 
    199204          } 
     205 
     206          if (in.getFilePointer() + 4 >= in.length()) break; 
    200207 
    201208          int num = in.readInt(); 
     
    296303      new FilterMetadata(getMetadataStore(), isMetadataFiltered()); 
    297304 
    298     while (in.getFilePointer() < in.length()) { 
     305    while (in.getFilePointer() + 8 < in.length()) { 
     306      long fp = in.getFilePointer(); 
    299307      readTagHeader(); 
     308      while (tag < IMAGE_TYPE_1 || tag > 76) { 
     309        fp--; 
     310        in.seek(fp); 
     311        readTagHeader(); 
     312      } 
    300313 
    301314      if (tag == IMAGE_TYPE_1 || tag == IMAGE_TYPE_2) { 
  • trunk/loci/formats/in/PictReader.java

    r4048 r4076  
    3232import loci.formats.meta.FilterMetadata; 
    3333import loci.formats.meta.MetadataStore; 
    34  
    35 // TODO : lots of duplicate code can be removed from this reader 
    3634 
    3735/** 
     
    5957  private static final int PICT_LONGCOMMENT = 0xa1; 
    6058 
    61   // possible image states 
    62   private static final int INITIAL = 1; 
    63   private static final int STATE2 = 2; 
    64  
    65   // other stuff? 
    66   private static final int INFOAVAIL = 2; 
    67   private static final int IMAGEAVAIL = 4; 
    68  
    6959  /** Table used in expanding pixels that use less than 8 bits. */ 
    7060  private static final byte[] EXPANSION_TABLE = new byte[256 * 8]; 
    7161 
    7262  static { 
    73     int index = 0; 
    7463    for (int i=0; i<256; i++) { 
    75       EXPANSION_TABLE[index++] = (i & 128) == 0 ? (byte) 0 : (byte) 1; 
    76       EXPANSION_TABLE[index++] = (i & 64) == 0 ? (byte) 0 : (byte) 1; 
    77       EXPANSION_TABLE[index++] = (i & 32) == 0 ? (byte) 0 : (byte) 1; 
    78       EXPANSION_TABLE[index++] = (i & 16) == 0 ? (byte) 0 : (byte) 1; 
    79       EXPANSION_TABLE[index++] = (i & 8) == 0 ? (byte) 0 : (byte) 1; 
    80       EXPANSION_TABLE[index++] = (i & 4) == 0 ? (byte) 0 : (byte) 1; 
    81       EXPANSION_TABLE[index++] = (i & 2) == 0 ? (byte) 0 : (byte) 1; 
    82       EXPANSION_TABLE[index++] = (i & 1) == 0 ? (byte) 0 : (byte) 1; 
     64      for (int j=0; j<8; j++) { 
     65        EXPANSION_TABLE[i*8 + j] = 
     66          (byte) ((i & (int) Math.pow(2, 7 - j)) >> 7 - j); 
     67      } 
    8368    } 
    8469  } 
    8570 
    8671  // -- Fields -- 
    87  
    88   /** Stream for reading pixel data. */ 
    89   protected RandomAccessStream ras; 
    90  
    91   /** Pixel bytes. */ 
    92   protected byte[] bytes; 
    9372 
    9473  /** Number of bytes in a row of pixel data (variable). */ 
    9574  protected int rowBytes; 
    96  
    97   /** Decoder state. */ 
    98   protected int state; 
    99  
    100   /** Image state. */ 
    101   protected int pictState; 
    10275 
    10376  /** Vector of byte arrays representing individual rows. */ 
     
    12598  public void setLegacy(boolean legacy) { 
    12699    this.legacy = legacy; 
    127   } 
    128  
    129   /** Get the dimensions of a PICT file from the first 4 bytes after header. */ 
    130   public Dimension getDimensions(byte[] stuff) throws FormatException { 
    131     if (stuff.length < 10) { 
    132       throw new FormatException("Need 10 bytes to calculate dimension"); 
    133     } 
    134     int w = DataTools.bytesToInt(stuff, 6, 2, core.littleEndian[0]); 
    135     int h = DataTools.bytesToInt(stuff, 8, 2, core.littleEndian[0]); 
    136     if (debug) debug("getDimensions: " + w + " x " + h); 
    137     return new Dimension(h, w); 
    138   } 
    139  
    140   /** Open a PICT image from an array of bytes (used by OpenlabReader). */ 
    141   public BufferedImage open(byte[] pix) throws FormatException, IOException { 
    142     if (legacy) return ImageTools.makeBuffered(qtTools.pictToImage(pix)); 
    143  
    144     // handles case when we call this method directly, instead of 
    145     // through initFile(String) 
    146     if (debug) debug("open"); 
    147  
    148     if (core == null) core = new CoreMetadata(1); 
    149  
    150     strips = new Vector(); 
    151  
    152     state = 0; 
    153     pictState = INITIAL; 
    154     bytes = pix; 
    155     ras = new RandomAccessStream(bytes); 
    156     ras.order(false); 
    157     rowBytes = 0; 
    158     versionOne = false; 
    159     lookup = null; 
    160  
    161     try { 
    162       while (driveDecoder()); 
    163     } 
    164     catch (FormatException exc) { 
    165       trace(exc); 
    166       return ImageTools.makeBuffered(qtTools.pictToImage(pix)); 
    167     } 
    168  
    169     // combine everything in the strips Vector 
    170  
    171     if ((core.sizeY[0]*4 < strips.size()) && (((strips.size() / 3) % 
    172       core.sizeY[0]) != 0)) 
    173     { 
    174       core.sizeY[0] = strips.size(); 
    175     } 
    176  
    177     if (strips.size() == 0) { 
    178       return ImageTools.makeBuffered(qtTools.pictToImage(pix)); 
    179     } 
    180  
    181     if (lookup != null) { 
    182       // 8 bit data 
    183       short[][] data = new short[3][core.sizeY[0] * core.sizeX[0]]; 
    184  
    185       byte[] row; 
    186  
    187       for (int i=0; i<core.sizeY[0]; i++) { 
    188         row = (byte[]) strips.get(i); 
    189  
    190         for (int j=0; j<row.length; j++) { 
    191           if (j < core.sizeX[0]) { 
    192             int ndx = row[j]; 
    193             if (ndx < 0) ndx += lookup[0].length; 
    194             ndx = ndx % lookup[0].length; 
    195  
    196             int outIndex = i*core.sizeX[0] + j; 
    197             if (outIndex >= data[0].length) outIndex = data[0].length - 1; 
    198  
    199             data[0][outIndex] = lookup[0][ndx]; 
    200             data[1][outIndex] = lookup[1][ndx]; 
    201             data[2][outIndex] = lookup[2][ndx]; 
    202           } 
    203           else j = row.length; 
    204         } 
    205       } 
    206  
    207       if (debug) { 
    208         debug("openBytes: 8-bit data, " + core.sizeX[0] + " x " + 
    209           core.sizeY[0] + ", length=" + data.length + "x" + data[0].length); 
    210       } 
    211       return ImageTools.makeImage(data, core.sizeX[0], core.sizeY[0]); 
    212     } 
    213     else if (core.sizeY[0]*3 == strips.size()) { 
    214       // 24 bit data 
    215       byte[][] data = new byte[3][core.sizeX[0] * core.sizeY[0]]; 
    216  
    217       int outIndex = 0; 
    218       for (int i=0; i<3*core.sizeY[0]; i+=3) { 
    219         byte[] c0 = (byte[]) strips.get(i); 
    220         byte[] c1 = (byte[]) strips.get(i+1); 
    221         byte[] c2 = (byte[]) strips.get(i+2); 
    222         System.arraycopy(c0, 0, data[0], outIndex, c0.length); 
    223         System.arraycopy(c1, 0, data[1], outIndex, c1.length); 
    224         System.arraycopy(c2, 0, data[2], outIndex, c2.length); 
    225         outIndex += core.sizeX[0]; 
    226       } 
    227  
    228       if (debug) { 
    229         debug("openBytes: 24-bit data, " + core.sizeX[0] + " x " + 
    230           core.sizeY[0] + ", length=" + data.length + "x" + data[0].length); 
    231       } 
    232       return ImageTools.makeImage(data, core.sizeX[0], core.sizeY[0]); 
    233     } 
    234     else if (core.sizeY[0]*4 == strips.size()) { 
    235       // 32 bit data 
    236       byte[][] data = new byte[3][core.sizeX[0] * core.sizeY[0]]; 
    237  
    238       int outIndex = 0; 
    239       for (int i=0; i<4*core.sizeY[0]; i+=4) { 
    240         //byte[] a = (byte[]) strips.get(i); 
    241         byte[] r = (byte[]) strips.get(i+1); 
    242         byte[] g = (byte[]) strips.get(i+2); 
    243         byte[] b = (byte[]) strips.get(i+3); 
    244         System.arraycopy(r, 0, data[0], outIndex, r.length); 
    245         System.arraycopy(g, 0, data[1], outIndex, g.length); 
    246         System.arraycopy(b, 0, data[2], outIndex, b.length); 
    247         //System.arraycopy(a, 0, data[3], outIndex, a.length); 
    248         outIndex += core.sizeX[0]; 
    249       } 
    250  
    251       if (debug) { 
    252         debug("openBytes: 32-bit data, " + core.sizeX[0] + " x " + 
    253           core.sizeY[0] + ", length=" + data.length + "x" + data[0].length); 
    254       } 
    255       return ImageTools.makeImage(data, core.sizeX[0], core.sizeY[0]); 
    256     } 
    257     else { 
    258       byte[] data = new byte[3 * core.sizeY[0] * core.sizeX[0]]; 
    259  
    260       int outIndex = 0; 
    261       for (int i=0; i<core.sizeY[0]; i++) { 
    262         int[] row = (int[]) strips.get(i); 
    263  
    264         for (int j=0; j<row.length; j++, outIndex+=3) { 
    265           if (j < core.sizeX[0]) { 
    266             if (outIndex >= data.length - 2) break; 
    267             data[outIndex] = (byte) ((row[j] & 0x7c00) >> 10); 
    268             data[outIndex+1] = (byte) ((row[j] & 0x3e0) >> 5); 
    269             data[outIndex+2] = (byte) (row[j] & 0x1f); 
    270           } 
    271           else j = row.length; 
    272         } 
    273       } 
    274  
    275       if (debug) { 
    276         debug("openBytes: 8-bit RGB data, " + core.sizeX[0] + " x " + 
    277           core.sizeY[0] + ", length=" + data.length); 
    278       } 
    279       return ImageTools.makeImage(data, core.sizeX[0], core.sizeY[0], 3, true); 
    280     } 
    281   } 
    282  
    283   // -- IFormatReader API methods -- 
    284  
    285   /* @see loci.formats.IFormatReader#isThisType(byte[]) */ 
    286   public boolean isThisType(byte[] block) { 
    287     if (block.length < 528) return false; 
    288     return true; 
    289100  } 
    290101 
     
    295106    throws FormatException, IOException 
    296107  { 
    297     FormatTools.checkBufferSize(this, buf.length); 
    298     byte[][] b = ImageTools.getPixelBytes(openImage(no, x, y, w, h), 
    299       core.littleEndian[0]); 
    300     for (int i=0; i<b.length; i++) { 
    301       System.arraycopy(b[i], 0, buf, i*b[i].length, b[i].length); 
     108    if (legacy || strips.size() == 0) { 
     109      in.seek(512); 
     110      byte[] pix = new byte[(int) (in.length() - in.getFilePointer())]; 
     111      in.read(pix); 
     112      byte[][] b = ImageTools.getPixelBytes(ImageTools.makeBuffered( 
     113        qtTools.pictToImage(pix)), core.littleEndian[0]); 
     114      for (int i=0; i<b.length; i++) { 
     115        System.arraycopy(b[i], 0, buf, i*b[i].length, b[i].length); 
     116      } 
     117      return buf; 
     118    } 
     119 
     120    // combine everything in the strips Vector 
     121 
     122    if ((core.sizeY[0]*4 < strips.size()) && (((strips.size() / 3) % 
     123      core.sizeY[0]) != 0)) 
     124    { 
     125      core.sizeY[0] = strips.size(); 
     126    } 
     127 
     128    int plane = core.sizeX[0] * core.sizeY[0]; 
     129 
     130    if (lookup != null) { 
     131      // 8 bit data 
     132 
     133      byte[] row; 
     134 
     135      plane *= 2; 
     136 
     137      for (int i=0; i<core.sizeY[0]; i++) { 
     138        row = (byte[]) strips.get(i); 
     139 
     140        for (int j=0; j<row.length; j++) { 
     141          if (j < core.sizeX[0]) { 
     142            int ndx = row[j]; 
     143            if (ndx < 0) ndx += lookup[0].length; 
     144            ndx = ndx % lookup[0].length; 
     145 
     146            int outIndex = i*core.sizeX[0]*2 + j*2; 
     147 
     148            if (2*plane + outIndex + 2 < buf.length) { 
     149              DataTools.unpackShort(lookup[0][ndx], buf, outIndex, false); 
     150              DataTools.unpackShort(lookup[1][ndx], buf, plane + outIndex, 
     151                false); 
     152              DataTools.unpackShort(lookup[2][ndx], buf, 2*plane + outIndex, 
     153                false); 
     154            } 
     155          } 
     156          else j = row.length; 
     157        } 
     158      } 
     159    } 
     160    else if (core.sizeY[0]*3 == strips.size() || 
     161      core.sizeY[0]*4 == strips.size()) 
     162    { 
     163      // 24 or 32 bit data 
     164 
     165      int nc = strips.size() / core.sizeY[0]; 
     166 
     167      for (int i=0; i<core.sizeY[0]; i++) { 
     168        byte[] c0 = (byte[]) strips.get(i * nc + nc - 3); 
     169        byte[] c1 = (byte[]) strips.get(i * nc + nc - 2); 
     170        byte[] c2 = (byte[]) strips.get(i * nc + nc - 1); 
     171        int baseOffset = i * core.sizeX[0]; 
     172        System.arraycopy(c0, 0, buf, baseOffset, core.sizeX[0]); 
     173        System.arraycopy(c1, 0, buf, plane + baseOffset, core.sizeX[0]); 
     174        System.arraycopy(c2, 0, buf, 2*plane + baseOffset, core.sizeX[0]); 
     175      } 
     176    } 
     177    else { 
     178      // RGB value is packed into a single short: xRRR RRGG GGGB BBBB 
     179      for (int i=0; i<core.sizeY[0]; i++) { 
     180        int[] row = (int[]) strips.get(i); 
     181 
     182        for (int j=0; j<row.length; j++) { 
     183          int base = i * row.length + j; 
     184          buf[base] = (byte) ((row[j] & 0x7c00) >> 10); 
     185          buf[plane + base] = (byte) ((row[j] & 0x3e0) >> 5); 
     186          buf[2 * plane + base] = (byte) (row[j] & 0x1f); 
     187        } 
     188      } 
    302189    } 
    303190    return buf; 
    304191  } 
    305192 
    306   /* @see loci.formats.IFormatReader#openImage(int, int, int, int, int) */ 
    307   public BufferedImage openImage(int no, int x, int y, int w, int h) 
    308     throws FormatException, IOException 
    309   { 
    310     FormatTools.assertId(currentId, true, 1); 
    311     FormatTools.checkPlaneNumber(this, no); 
    312  
    313     return open(bytes).getSubimage(x, y, w, h); 
     193  // -- IFormatReader API methods -- 
     194 
     195  /* @see loci.formats.IFormatReader#isThisType(byte[]) */ 
     196  public boolean isThisType(byte[] block) { 
     197    return block.length >= 528; 
    314198  } 
    315199 
     
    326210    core.littleEndian[0] = false; 
    327211 
    328     // skip the header and read in the remaining bytes 
    329     int len = (int) (in.length() - 512); 
    330     bytes = new byte[len]; 
    331     in.seek(512); 
    332     in.read(bytes); 
    333  
    334     byte[] b = new byte[20]; 
    335     in.seek(512); 
    336     in.read(b); 
    337     Dimension d = getDimensions(b); 
    338  
    339     core.sizeX[0] = d.width; 
    340     core.sizeY[0] = d.height; 
     212    in.seek(518); 
     213 
     214    core.sizeY[0] = in.readShort(); 
     215    core.sizeX[0] = in.readShort(); 
    341216    core.sizeZ[0] = 1; 
    342217    core.sizeC[0] = 3; 
     
    344219    core.currentOrder[0] = "XYCZT"; 
    345220    core.rgb[0] = true; 
    346     core.interleaved[0] = false; 
    347221    core.imageCount[0] = 1; 
    348222    core.indexed[0] = false; 
    349223    core.falseColor[0] = false; 
    350224    core.metadataComplete[0] = true; 
     225    core.interleaved[0] = false; 
     226 
     227    strips = new Vector(); 
     228    rowBytes = 0; 
     229    versionOne = false; 
     230    lookup = null; 
     231 
     232    int opcode; 
     233 
     234    int verOpcode = in.read(); 
     235    int verNumber = in.read(); 
     236 
     237    if (verOpcode == 0x11 && verNumber == 0x01) versionOne = true; 
     238    else if (verOpcode == 0x00 && verNumber == 0x11) { 
     239      versionOne = false; 
     240      int verNumber2 = in.readShort(); 
     241 
     242      if (verNumber2 != 0x02ff) { 
     243        throw new FormatException("Invalid PICT file : " + verNumber2); 
     244      } 
     245 
     246      // skip over v2 header -- don't need it here 
     247      //in.skipBytes(26); 
     248      in.skipBytes(6); 
     249      int pixelsPerInchX = in.readInt(); 
     250      int pixelsPerInchY = in.readInt(); 
     251      in.skipBytes(12); 
     252    } 
     253    else throw new FormatException("Invalid PICT file"); 
     254 
     255    do { 
     256      if (versionOne) opcode = in.read(); 
     257      else { 
     258        // if at odd boundary skip a byte for opcode in PICT v2 
     259 
     260        if ((in.getFilePointer() & 0x1L) != 0) { 
     261          in.skipBytes(1); 
     262        } 
     263        opcode = in.readShort(); 
     264      } 
     265    } 
     266    while (drivePictDecoder(opcode)); 
     267 
     268    core.pixelType[0] = lookup != null ? FormatTools.UINT16 : FormatTools.UINT8; 
    351269 
    352270    // The metadata store we're working with. 
     
    357275      DataTools.convertDate(System.currentTimeMillis(), DataTools.UNIX), 0); 
    358276 
    359     core.pixelType[0] = ImageTools.getPixelType(openImage(0)); 
    360  
    361277    MetadataTools.populatePixels(store, this); 
    362     // CTR CHECK 
    363 //    for (int i=0; i<core.sizeC[0]; i++) { 
    364 //      store.setLogicalChannel(i, null, null, null, null, null, null, null, 
    365 //        null, null, null, null, null, null, null, null, null, null, null, null, 
    366 //        null, null, null, null, null); 
    367 //    } 
    368278  } 
    369279 
    370280  // -- Helper methods -- 
    371  
    372   /** Loop through the remainder of the file and find relevant opcodes. */ 
    373   private boolean driveDecoder() throws FormatException, IOException { 
    374     if (debug) debug("driveDecoder"); 
    375     int opcode; 
    376  
    377     switch (pictState) { 
    378       case INITIAL: 
    379         ras.skipBytes(10); 
    380         int verOpcode = ras.read(); 
    381         int verNumber = ras.read(); 
    382  
    383         if (verOpcode == 0x11 && verNumber == 0x01) versionOne = true; 
    384         else if (verOpcode == 0x00 && verNumber == 0x11) { 
    385           versionOne = false; 
    386           int verNumber2 = ras.readShort(); 
    387  
    388           if (verNumber2 != 0x02ff) { 
    389             throw new FormatException("Invalid PICT file : " + verNumber2); 
    390           } 
    391  
    392           // skip over v2 header -- don't need it here 
    393           ras.skipBytes(26); 
    394         } 
    395         else throw new FormatException("Invalid PICT file"); 
    396  
    397         pictState = STATE2; 
    398         state |= INFOAVAIL; 
    399         return true; 
    400  
    401       case STATE2: 
    402         if (versionOne) opcode = ras.read(); 
    403         else { 
    404           // if at odd boundary skip a byte for opcode in PICT v2 
    405  
    406           if ((ras.getFilePointer() & 0x1L) != 0) { 
    407             ras.skipBytes(1); 
    408           } 
    409           opcode = ras.readShort(); 
    410         } 
    411         return drivePictDecoder(opcode); 
    412     } 
    413     return true; 
    414   } 
    415281 
    416282  /** Handles the opcodes in the PICT file. */ 
     
    418284    throws FormatException, IOException 
    419285  { 
    420     if (debug) debug("drivePictDecoder"); 
     286    if (debug) debug("drivePictDecoder(" + opcode + ") @ " + in.getFilePointer()); 
    421287 
    422288    switch (opcode) { 
     
    425291      case PICT_BITSRECT: // rowBytes must be < 8 
    426292      case PICT_PACKBITSRECT: 
     293        rowBytes = in.readShort(); 
     294        if (versionOne || (rowBytes & 0x8000) == 0) handleBitmap(opcode); 
     295        else handlePixmap(opcode); 
     296        break; 
    427297      case PICT_9A: 
    428         handlePackBits(opcode); 
     298        handlePixmap(opcode); 
    429299        break; 
    430300      case PICT_CLIP_RGN: 
    431         int x = ras.readShort(); 
    432         ras.skipBytes(x - 2); 
     301        int x = in.readShort(); 
     302        in.skipBytes(x - 2); 
    433303        break; 
    434304      case PICT_LONGCOMMENT: 
    435         ras.skipBytes(2); 
    436         x = ras.readShort(); 
    437         ras.skipBytes(x); 
     305        in.skipBytes(2); 
     306        x = in.readShort(); 
     307        in.skipBytes(x); 
    438308        break; 
    439309      case PICT_END: // end of PICT 
    440         state |= IMAGEAVAIL; 
    441310        return false; 
    442     } 
    443  
    444     return ras.getFilePointer() < ras.length(); 
    445   } 
    446  
    447   /** Handles bitmap and pixmap opcodes of PICT format. */ 
    448   private void handlePackBits(int opcode) 
    449     throws FormatException, IOException 
    450   { 
    451     if (debug) debug("handlePackBits(" + opcode + ")"); 
    452     if (opcode == PICT_9A) { 
    453       // special case 
    454       handlePixmap(opcode); 
    455     } 
    456     else { 
    457       rowBytes = ras.readShort(); 
    458       if (versionOne || (rowBytes & 0x8000) == 0) handleBitmap(opcode); 
    459       else handlePixmap(opcode); 
    460     } 
     311      default: 
     312        if (opcode < 0) { 
     313          throw new FormatException("Invalid opcode: " + opcode); 
     314        } 
     315    } 
     316 
     317    return in.getFilePointer() < in.length(); 
     318  } 
     319 
     320  private void readImageHeader(int opcode) throws IOException { 
     321    if (opcode == PICT_9A) in.skipBytes(6); 
     322    else rowBytes &= 0x3fff; 
     323 
     324    int tlY = in.readShort(); 
     325    int tlX = in.readShort(); 
     326    int brY = in.readShort(); 
     327    int brX = in.readShort(); 
     328 
     329    core.sizeX[0] = brX - tlX; 
     330    core.sizeY[0] = brY - tlY; 
     331 
     332    in.skipBytes(18); 
    461333  } 
    462334 
     
    465337    throws FormatException, IOException 
    466338  { 
    467     if (debug) debug("handleBitmap(" + opcode + ")"); 
    468     int row; 
    469     byte[] buf;  // raw byte buffer for data from file 
    470     byte[] uBuf; // uncompressed data -- possibly still pixel packed 
    471     byte[] outBuf; // expanded pixel data 
    472  
    473     rowBytes &= 0x3fff;  // mask off flags 
    474  
    475     // read the bitmap data -- 3 rectangles + mode 
    476  
    477     int tlY = ras.readShort(); 
    478     int tlX = ras.readShort(); 
    479     int brY = ras.readShort(); 
    480     int brX = ras.readShort(); 
    481  
    482     // skip next two rectangles 
    483     ras.skipBytes(18); 
    484  
    485     core.sizeX[0] = brX - tlX; 
    486     core.sizeY[0] = brY - tlY; 
    487  
    488     // allocate enough space to handle compressed data length for rowBytes 
    489  
    490     try { 
    491       buf = new byte[rowBytes + 1 + rowBytes/128]; 
    492       uBuf = new byte[rowBytes]; 
    493       outBuf = new byte[core.sizeX[0]]; 
    494     } 
    495     catch (NegativeArraySizeException n) { 
    496       throw new FormatException("Sorry, vector data not supported."); 
    497     } 
    498  
    499     for (row=0; row < core.sizeY[0]; ++row) { 
    500       if (rowBytes < 8) {  // data is not compressed 
    501         ras.read(buf, 0, rowBytes); 
    502  
    503         for (int j=buf.length; --j >= 0;) { 
    504           buf[j] = (byte) ~buf[j]; 
    505         } 
    506         expandPixels(1, buf, outBuf, outBuf.length); 
    507       } 
    508       else { 
    509         int rawLen; 
    510         if (rowBytes > 250) rawLen = ras.readShort(); 
    511         else rawLen = ras.read(); 
    512  
    513         try { 
    514           ras.read(buf, 0, rawLen); 
    515         } 
    516         catch (ArrayIndexOutOfBoundsException e) { 
    517           throw new FormatException("Sorry, vector data not supported."); 
    518         } 
    519  
    520         PackbitsCodec c = new PackbitsCodec(); 
    521         uBuf = c.decompress(buf, new Integer(core.sizeX[0] * 4)); 
    522  
    523         // invert the pixels -- PICT images map zero to white 
    524         for (int j=0; j<uBuf.length; j++) uBuf[j] = (byte) ~uBuf[j]; 
    525  
    526         expandPixels(1, uBuf, outBuf, outBuf.length); 
    527       } 
    528       strips.add(outBuf); 
    529     } 
     339    readImageHeader(opcode); 
     340    handlePixmap(rowBytes, 1, 1); 
    530341  } 
    531342 
     
    534345    throws FormatException, IOException 
    535346  { 
     347    readImageHeader(opcode); 
    536348    if (debug) debug("handlePixmap(" + opcode + ")"); 
    537     int pixelSize; 
    538     int compCount; 
    539  
    540     // handle 9A variation 
     349 
     350    int pixelSize = in.readShort(); 
     351    int compCount = in.readShort(); 
     352    in.skipBytes(14); 
     353 
    541354    if (opcode == PICT_9A) { 
    542       // this is the only opcode that holds 16, 24, and 32 bit data 
    543  
    544       // read the pixmap (9A) 
    545  
    546       ras.skipBytes(6); 
    547  
    548       // read the bounding box 
    549       int tlY = ras.readShort(); 
    550       int tlX = ras.readShort(); 
    551       int brY = ras.readShort(); 
    552       int brX = ras.readShort(); 
    553  
    554       ras.skipBytes(18); 
    555  
    556       pixelSize = ras.readShort(); 
    557       compCount = ras.readShort(); 
    558       ras.skipBytes(14); 
    559  
    560       core.sizeX[0] = brX - tlX; 
    561       core.sizeY[0] = brY - tlY; 
    562  
    563355      // rowBytes doesn't exist, so set it to its logical value 
    564356      switch (pixelSize) { 
     
    574366    } 
    575367    else { 
    576       rowBytes &= 0x3fff;  // mask off flags 
    577  
    578       int tlY = ras.readShort(); 
    579       int tlX = ras.readShort(); 
    580       int brY = ras.readShort(); 
    581       int brX = ras.readShort(); 
    582  
    583       ras.skipBytes(18); 
    584  
    585       pixelSize = ras.readShort(); 
    586       compCount = ras.readShort(); 
    587  
    588       ras.skipBytes(14); 
    589  
    590368      // read the lookup table 
    591369 
    592       ras.skipBytes(4); 
    593       int flags = ras.readShort(); 
    594       int count = ras.readShort(); 
     370      in.skipBytes(4); 
     371      int flags = in.readShort(); 
     372      int count = in.readShort(); 
    595373 
    596374      count++; 
     
    598376 
    599377      for (int i=0; i<count; i++) { 
    600         int index = ras.readShort(); 
     378        int index = in.readShort(); 
    601379        if ((flags & 0x8000) != 0) index = i; 
    602         lookup[0][index] = ras.readShort(); 
    603         lookup[1][index] = ras.readShort(); 
    604         lookup[2][index] = ras.readShort(); 
    605       } 
    606  
    607       core.sizeX[0] = brX - tlX; 
    608       core.sizeY[0] = brY - tlY; 
     380        lookup[0][index] = in.readShort(); 
     381        lookup[1][index] = in.readShort(); 
     382        lookup[2][index] = in.readShort(); 
     383      } 
    609384    } 
    610385 
    611386    // skip over two rectangles 
    612     ras.skipBytes(18); 
    613  
    614     if (opcode == PICT_BITSRGN || opcode == PICT_PACKBITSRGN) ras.skipBytes(2); 
     387    in.skipBytes(18); 
     388 
     389    if (opcode == PICT_BITSRGN || opcode == PICT_PACKBITSRGN) in.skipBytes(2); 
    615390 
    616391    handlePixmap(rowBytes, pixelSize, compCount); 
     
    664439      buf = new byte[bufSize]; 
    665440      for (int row=0; row<core.sizeY[0]; row++) { 
    666         ras.read(buf, 0, rBytes); 
     441        in.read(buf, 0, rBytes); 
    667442 
    668443        switch (pixelSize) { 
    669444          case 16: 
    670445            for (int i=0; i<core.sizeX[0]; i++) { 
    671               uBufI[i] = ((buf[i*2] & 0xff) << 8) + (buf[i*2+1] & 0xff); 
     446              uBufI[i] = DataTools.bytesToShort(buf, i*2, 2, false); 
    672447            } 
    673448            strips.add(uBufI); 
     
    689464      buf = new byte[bufSize + 1 + bufSize / 128]; 
    690465      for (int row=0; row<core.sizeY[0]; row++) { 
    691         if (rBytes > 250) rawLen = ras.readShort(); 
    692         else rawLen = ras.read(); 
     466        if (rBytes > 250) rawLen = in.readShort(); 
     467        else rawLen = in.read(); 
    693468 
    694469        if (rawLen > buf.length) rawLen = buf.length; 
    695470 
    696         if ((ras.length() - ras.getFilePointer()) <= rawLen) { 
    697           rawLen = (int) (ras.length() - ras.getFilePointer() - 1); 
     471        if ((in.length() - in.getFilePointer()) <= rawLen) { 
     472          rawLen = (int) (in.length() - in.getFilePointer() - 1); 
    698473        } 
    699474 
    700475        if (rawLen < 0) { 
    701476          rawLen = 0; 
    702           ras.seek(ras.length() - 1); 
    703         } 
    704  
    705         ras.read(buf, 0, rawLen); 
     477          in.seek(in.length() - 1); 
     478        } 
     479 
     480        in.read(buf, 0, rawLen); 
    706481 
    707482        if (pixelSize == 16) { 
     
    722497        else if (pixelSize == 24 || pixelSize == 32) { 
    723498          byte[] newBuf = null; 
    724           int offset = 0; 
    725  
    726           if (compCount == 4) { 
    727             // alpha channel 
    728             //newBuf = new byte[width]; 
    729             //System.arraycopy(uBuf, offset, newBuf, 0, width); 
     499 
     500          for (int q=0; q<compCount; q++) { 
     501            int offset = q * core.sizeX[0]; 
     502            int len = (int) Math.min(core.sizeX[0], uBuf.length - offset); 
     503            newBuf = new byte[core.sizeX[0]]; 
     504            if (offset < uBuf.length) { 
     505              System.arraycopy(uBuf, offset, newBuf, 0, len); 
     506            } 
    730507            strips.add(newBuf); 
    731             offset += core.sizeX[0]; 
    732508          } 
    733  
    734           // red channel 
    735           newBuf = new byte[core.sizeX[0]]; 
    736           System.arraycopy(uBuf, offset, newBuf, 0, core.sizeX[0]); 
    737           strips.add(newBuf); 
    738           offset += core.sizeX[0]; 
    739  
    740           // green channel 
    741           newBuf = new byte[core.sizeX[0]]; 
    742           System.arraycopy(uBuf, offset, newBuf, 0, core.sizeX[0]); 
    743           strips.add(newBuf); 
    744           offset += core.sizeX[0]; 
    745  
    746           // blue channel 
    747           newBuf = new byte[core.sizeX[0]]; 
    748           System.arraycopy(uBuf, offset, newBuf, 0, core.sizeX[0]); 
    749           strips.add(newBuf); 
    750509        } 
    751510      } 
     
    782541    } 
    783542 
    784     int i; 
    785     int o; 
    786     int t; 
    787543    byte v; 
    788544    int count = 8 / bitSize; // number of pixels in a byte 
     
    791547    int tpixelshift = 0; 
    792548    int pixelshiftdelta = bitSize; 
    793     int mask = 0; 
    794549    int tmask; // temp mask 
    795550 
     
    798553    } 
    799554 
    800     switch (bitSize) { 
    801       case 1: 
    802         mask = 0x80; 
    803         break; 
    804       case 2: 
    805         mask = 0xC0; 
    806         break; 
    807       case 4: 
    808         mask = 0xF0; 
    809         break; 
    810     } 
    811  
    812     i = 0; 
    813     for (o = 0; o < ob.length;) { 
     555    int mask = ((int) Math.pow(2, bitSize) - 1) << (8 - bitSize); 
     556 
     557    int i = 0; 
     558    for (int o = 0; o < ob.length; i++) { 
    814559      tmask = mask; 
    815560      tpixelshift = pixelshift; 
    816561      v = ib[i]; 
    817       for (t = 0; t < count && o < ob.length; ++t, ++o) { 
     562      for (int t = 0; t < count && o < ob.length; t++, o++) { 
    818563        ob[o] = (byte) (((v & tmask) >>> tpixelshift) & 0xff); 
    819564        tmask = (byte) ((tmask & 0xff) >>> maskshift); 
    820565        tpixelshift -= pixelshiftdelta; 
    821566      } 
    822       ++i; 
    823567    } 
    824568  } 
     
    828572    if (debug) debug("unpackBits(" + ib + ", " + ob + ")"); 
    829573    int i = 0; 
    830     int o = 0; 
    831574    int b; 
    832575    int rep; 
    833576    int end; 
    834577 
    835     for (o=0; o<ob.length;) { 
     578    for (int o=0; o<ob.length;) { 
    836579      if (i+1 < ib.length) { 
    837580        b = ib[i++]; 
    838581        if (b >= 0) { 
    839           b++; 
    840           end = o + b; 
    841           for(; o < end; o++, i+=2) { 
    842             if (o < ob.length && (i+1) < ib.length) { 
    843               ob[o] = (((ib[i] & 0xff) << 8) + (ib[i+1] & 0xff)) & 0xffff; 
    844             } 
    845             else o = end; 
     582          end = o + b + 1; 
     583          while (o < end && o < ob.length && (i + 1) < ib.length) { 
     584            ob[o++] = DataTools.bytesToShort(ib, i, 2, false); 
     585            i += 2; 
    846586          } 
    847587        } 
    848588        else if (b != -128) { 
    849           rep = (((ib[i] & 0xff) << 8) + (ib[i+1] & 0xff)) & 0xffff; 
     589          rep = DataTools.bytesToShort(ib, i, 2, false); 
    850590          i += 2; 
    851591          end = o - b + 1; 
    852           for (; o < end; o++) { 
    853             if (o < ob.length) ob[o] = rep; 
    854             else o = end; 
     592          while (o < end && o < ob.length) { 
     593            ob[o++] = rep; 
    855594          } 
    856595        } 
Note: See TracChangeset for help on using the changeset viewer.