Changeset 3900


Ignore:
Timestamp:
04/08/08 15:24:56 (12 years ago)
Author:
melissa
Message:

Fixed a bunch of TIFF problems. Some stuff is still broken - namely 2, 4, 10 and 12 bit images.

Location:
trunk/loci/formats
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/ChannelFiller.java

    r3663 r3900  
    2929import loci.formats.meta.*; 
    3030 
    31 /* 
     31/** 
    3232 * Expands indexed color images to RGB. 
    3333 * 
  • trunk/loci/formats/TiffTools.java

    r3886 r3900  
    964964    boolean fakeByteCounts = stripByteCounts == null; 
    965965    boolean fakeRPS = rowsPerStripArray == null; 
    966     boolean isTiled = stripOffsets == null; 
     966    boolean isTiled = stripOffsets == null || 
     967      ifd.get(new Integer(TILE_WIDTH)) != null; 
    967968 
    968969    long[] maxes = getIFDLongArray(ifd, MAX_SAMPLE_VALUE, false); 
     
    970971 
    971972    if (isTiled) { 
    972       stripOffsets = getIFDLongArray(ifd, TILE_OFFSETS, true); 
    973       stripByteCounts = getIFDLongArray(ifd, TILE_BYTE_COUNTS, true); 
     973      if (stripOffsets == null) { 
     974        stripOffsets = getIFDLongArray(ifd, TILE_OFFSETS, true); 
     975      } 
     976      if (stripByteCounts == null) { 
     977        stripByteCounts = getIFDLongArray(ifd, TILE_BYTE_COUNTS, true); 
     978      } 
    974979      rowsPerStripArray = new long[] {imageLength}; 
    975980    } 
     
    12961301    byte[] altBytes = new byte[0]; 
    12971302 
    1298     if (bitsPerSample[0] == 16) littleEndian = !littleEndian; 
    1299  
    13001303    byte[] jpegTable = null; 
    13011304    if (compression == JPEG) { 
     
    13741377      undifference(buf, bitsPerSample, imageWidth, planarConfig, predictor, 
    13751378        littleEndian); 
    1376       unpackBytes(buf, 0, buf, bitsPerSample, photoInterp, colorMap, 
     1379      byte[] tmp = new byte[buf.length]; 
     1380      System.arraycopy(buf, 0, tmp, 0, tmp.length); 
     1381      Arrays.fill(buf, (byte) 0); 
     1382      unpackBytes(buf, 0, tmp, bitsPerSample, photoInterp, colorMap, 
    13771383        littleEndian, maxValue, planarConfig, 0, 1, imageWidth); 
    13781384    } 
    13791385    else { 
    1380       int overallOffset = 0; 
    1381  
    13821386      int offset = 0; 
    13831387 
     
    14281432            undifference(bytes, bitsPerSample, 
    14291433              imageWidth, planarConfig, predictor, littleEndian); 
    1430             if (planarConfig == 2) { 
    1431               offset = overallOffset / samplesPerPixel; 
    1432             } 
    14331434 
    14341435            if (x != 0 || width != imageWidth || y != 0 || 
     
    14571458              photoInterp, colorMap, littleEndian, maxValue, planarConfig, 
    14581459              strip, (int) numStrips, width); 
    1459             overallOffset += bytes.length / bitsPerSample.length; 
    1460             offset += width * nRows; 
     1460            int div = bitsPerSample[0] / 8; 
     1461            if (div == 0) div = 1; 
     1462            if (bitsPerSample[0] % 8 != 0) div++; 
     1463            if (planarConfig != 2) div *= samplesPerPixel; 
     1464            offset += bytes.length / div; 
    14611465          } 
    14621466          else { 
     
    14801484            predictor, littleEndian); 
    14811485          offset = (int) (imageWidth * row); 
    1482           if (planarConfig == 2) offset = overallOffset / samplesPerPixel; 
    14831486          unpackBytes(buf, offset, bytes, bitsPerSample, photoInterp, 
    14841487            colorMap, littleEndian, maxValue, planarConfig, 
    14851488            strip, (int) numStrips, imageWidth); 
    1486           overallOffset += bytes.length / bitsPerSample.length; 
    14871489        } 
    14881490      } 
     
    15021504        byte[] tmp = new byte[(int) 
    15031505          (imageWidth * imageLength * bitsPerSample.length * bpp)]; 
    1504         unpackBytes(tmp, (int) imageWidth, altBytes, bitsPerSample, 
     1506        unpackBytes(tmp, 0, altBytes, bitsPerSample, 
    15051507          photoInterp, colorMap, littleEndian, maxValue, planarConfig, 0, 1, 
    15061508          imageWidth); 
     
    15151517      } 
    15161518      else { 
    1517         unpackBytes(buf, (int) imageWidth, altBytes, bitsPerSample, 
     1519        unpackBytes(buf, 0, altBytes, bitsPerSample, 
    15181520          photoInterp, colorMap, littleEndian, maxValue, planarConfig, 0, 1, 
    15191521          imageWidth); 
     
    15221524 
    15231525    return buf; 
    1524   } 
    1525  
    1526   /** Reads the image defined in the given IFD from the specified file. */ 
    1527   public static BufferedImage getImage(Hashtable ifd, RandomAccessStream in) 
    1528     throws FormatException, IOException 
    1529   { 
    1530     // construct field 
    1531     if (DEBUG) debug("constructing image"); 
    1532  
    1533     byte[][] samples = getSamples(ifd, in); 
    1534     int[] bitsPerSample = getBitsPerSample(ifd); 
    1535     long imageWidth = getImageWidth(ifd); 
    1536     long imageLength = getImageLength(ifd); 
    1537     int samplesPerPixel = getSamplesPerPixel(ifd); 
    1538  
    1539     if (bitsPerSample[0] == 16 || bitsPerSample[0] == 12) { 
    1540       // First wrap the byte arrays and then use the features of the 
    1541       // ByteBuffer to transform to a ShortBuffer. Finally, use the ShortBuffer 
    1542       // bulk get method to copy the data into a usable form for makeImage(). 
    1543       int len = samples.length == 2 ? 3 : samples.length; 
    1544  
    1545       short[][] sampleData = new short[len][samples[0].length / 2]; 
    1546       for (int i = 0; i < samplesPerPixel; i++) { 
    1547         ShortBuffer sampleBuf = ByteBuffer.wrap(samples[i]).asShortBuffer(); 
    1548         sampleBuf.get(sampleData[i]); 
    1549       } 
    1550  
    1551       // Now make our image. 
    1552       return ImageTools.makeImage(sampleData, 
    1553         (int) imageWidth, (int) imageLength); 
    1554     } 
    1555     else if (bitsPerSample[0] == 24) { 
    1556       int[][] intData = new int[samplesPerPixel][samples[0].length / 3]; 
    1557       for (int i=0; i<samplesPerPixel; i++) { 
    1558         for (int j=0; j<intData[i].length; j++) { 
    1559           intData[i][j] = DataTools.bytesToInt(samples[i], j*3, 3, 
    1560             isLittleEndian(ifd)); 
    1561         } 
    1562       } 
    1563       return ImageTools.makeImage(intData, (int) imageWidth, (int) imageLength); 
    1564     } 
    1565     else if (bitsPerSample[0] == 32) { 
    1566       int type = getIFDIntValue(ifd, SAMPLE_FORMAT); 
    1567       if (type == 3) { 
    1568         // float data 
    1569         float[][] floatData = new float[samplesPerPixel][samples[0].length / 4]; 
    1570         for (int i=0; i<samplesPerPixel; i++) { 
    1571           floatData[i] = (float[]) DataTools.makeDataArray(samples[i], 4, true, 
    1572             isLittleEndian(ifd)); 
    1573         } 
    1574         return ImageTools.makeImage(floatData, 
    1575           (int) imageWidth, (int) imageLength); 
    1576       } 
    1577       else { 
    1578         // int data 
    1579         int[][] intData = new int[samplesPerPixel][samples[0].length / 4]; 
    1580         for (int i=0; i<samplesPerPixel; i++) { 
    1581           IntBuffer sampleBuf = ByteBuffer.wrap(samples[i]).asIntBuffer(); 
    1582           sampleBuf.get(intData[i]); 
    1583         } 
    1584  
    1585         byte[][] shortData = new byte[samplesPerPixel][intData[0].length]; 
    1586         for (int i=0; i<samplesPerPixel; i++) { 
    1587           for (int j=0; j<shortData[0].length; j++) { 
    1588             shortData[i][j] = (byte) intData[i][j]; 
    1589           } 
    1590         } 
    1591  
    1592         return ImageTools.makeImage(shortData, 
    1593           (int) imageWidth, (int) imageLength); 
    1594       } 
    1595     } 
    1596     if (samplesPerPixel == 1) { 
    1597       return ImageTools.makeImage(samples[0], (int) imageWidth, 
    1598         (int) imageLength, 1, false); 
    1599     } 
    1600  
    1601     return ImageTools.makeImage(samples, (int) imageWidth, (int) imageLength); 
    16021526  } 
    16031527 
     
    16131537    int strip, int numStrips) throws FormatException 
    16141538  { 
    1615     int numChannels = bitsPerSample.length;  // this should always be 3 
     1539    int numChannels = bitsPerSample.length; 
    16161540    int numSamples = samples.length / numChannels; 
    16171541    if (bitsPerSample[bitsPerSample.length - 1] == 0) numChannels--; 
     
    16211545    int channelNum = strip / (numStrips / numChannels); 
    16221546 
    1623     startIndex = (strip % (numStrips / numChannels)) * bytes.length; 
     1547    BitBuffer bb = new BitBuffer(bytes); 
    16241548 
    16251549    int index = 0; 
    16261550    int counter = 0; 
    16271551    int numBytes = bitsPerSample[0] / 8; 
    1628     for (int j=0; j<bytes.length; j++) { 
    1629  
    1630       if (bitsPerSample[0] % 8 != 0) { 
    1631         // bits per sample is not a multiple of 8 
    1632         // 
    1633         // while images in this category are not in violation of baseline TIFF 
    1634         // specs, it's a bad idea to write bits per sample values that aren't 
    1635         // divisible by 8 
    1636  
    1637         if (index == bytes.length) { 
    1638           //throw new FormatException("bad index : i = " + i + ", j = " + j); 
    1639           index--; 
    1640         } 
    1641  
    1642         short b = bytes[index]; 
    1643         index++; 
    1644  
    1645         int offset = (bitsPerSample[0] * (numChannels*j + channelNum)) % 8; 
    1646         if (offset <= (8 - (bitsPerSample[0] % 8))) { 
    1647           index--; 
    1648         } 
    1649  
    1650         if (channelNum == 0) counter++; 
    1651         if (counter % 4 == 0 && channelNum == 0) { 
    1652           index++; 
    1653         } 
    1654  
    1655         int ndx = startIndex + j; 
    1656         if (ndx >= numSamples) { 
    1657           ndx = numSamples - 1; 
    1658         } 
    1659         samples[channelNum*numSamples + ndx] = (byte) (b < 0 ? 256 + b : b); 
    1660  
    1661         if (photoInterp == WHITE_IS_ZERO || photoInterp == CMYK) { 
    1662           samples[channelNum*numSamples + ndx] = 
    1663             (byte) (Integer.MAX_VALUE - samples[channelNum*numSamples + ndx]); 
    1664         } 
    1665       } 
    1666       else if (numBytes == 1) { 
    1667         float b = bytes[index++]; 
    1668  
    1669         int ndx = startIndex + j; 
    1670         if (ndx < numSamples) { 
    1671           samples[channelNum*numSamples + ndx] = (byte) (b < 0 ? 256 + b : b); 
    1672  
    1673           if (photoInterp == WHITE_IS_ZERO) { // invert color value 
    1674             samples[channelNum*numSamples + ndx] = 
    1675               (byte) ((65535 - samples[channelNum*numSamples + ndx]) & 0xffff); 
    1676           } 
    1677           else if (photoInterp == CMYK) { 
    1678             samples[channelNum*numSamples + ndx] = 
    1679               (byte) (Integer.MAX_VALUE - samples[channelNum*numSamples + ndx]); 
    1680           } 
    1681         } 
    1682       } 
    1683       else { 
    1684         byte[] b = new byte[numBytes]; 
    1685         if (numBytes + index < bytes.length) { 
    1686           System.arraycopy(bytes, index, b, 0, numBytes); 
    1687         } 
    1688         else { 
    1689           System.arraycopy(bytes, bytes.length - numBytes, b, 0, numBytes); 
    1690         } 
    1691         index += numBytes; 
    1692         long v = DataTools.bytesToLong(b, littleEndian); 
    1693  
    1694         if (photoInterp == WHITE_IS_ZERO) { // invert color value 
    1695           long max = 1; 
    1696           for (int q=0; q<numBytes; q++) max *= 8; 
    1697           v = max - v; 
    1698         } 
    1699         else if (photoInterp == CMYK) { 
    1700           v = Integer.MAX_VALUE - v; 
    1701         } 
    1702         DataTools.unpackBytes(v, samples, 
    1703           channelNum*numSamples + j*numBytes, numBytes, littleEndian); 
    1704       } 
     1552    if (bitsPerSample[0] % 8 != 0) numBytes++; 
     1553    int realBytes = numBytes; 
     1554    if (numBytes == 3) numBytes++; 
     1555 
     1556    for (int j=0; j<bytes.length / realBytes; j++) { 
     1557      int value = bb.getBits(bitsPerSample[0]); 
     1558 
     1559      if (photoInterp == WHITE_IS_ZERO) { 
     1560        value = (int) (Math.pow(2, bitsPerSample[0]) - 1 - value); 
     1561      } 
     1562      else if (photoInterp == CMYK) { 
     1563        value = Integer.MAX_VALUE - value; 
     1564      } 
     1565 
     1566      DataTools.unpackBytes(value, samples, numBytes*(startIndex + j), 
     1567        numBytes, littleEndian); 
    17051568    } 
    17061569  } 
     
    17341597      debug("unpacking " + sampleCount + " samples (startIndex=" + startIndex + 
    17351598        "; totalBits=" + totalBits + "; numBytes=" + bytes.length + ")"); 
    1736     } 
    1737     if (startIndex + sampleCount > nSamples) { 
    1738       int trunc = startIndex + sampleCount - nSamples; 
    1739       if (DEBUG) debug("WARNING: truncated " + trunc + " extra samples"); 
    1740       sampleCount -= trunc; 
    17411599    } 
    17421600 
     
    17791637 
    17801638    byte[] copyByteArray = new byte[numBytes]; 
    1781     ByteBuffer nioBytes = MappedByteBuffer.wrap(bytes); 
    1782     nioBytes.order(littleEndian ? 
    1783       ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); 
    17841639 
    17851640    for (int j=0; j<sampleCount; j++) { 
     
    17941649            photoInterp != RGB_PALETTE))) 
    17951650          { 
    1796             s = (short) bb.getBits(bps0); 
    1797             if ((ndx % imageWidth) == imageWidth - 1) { 
     1651            s = (short) (bb.getBits(bps0) & 0xffff); 
     1652            if ((ndx % imageWidth) == imageWidth - 1 && bps0 < 8) { 
    17981653              bb.skipBits((imageWidth * bps0 * sampleCount) % 8); 
    17991654            } 
    18001655          } 
    1801           if (photoInterp != CFA_ARRAY) samples[i*nSamples + ndx] = (byte) s; 
    18021656 
    18031657          if (photoInterp == WHITE_IS_ZERO || photoInterp == CMYK) { 
    18041658            // invert colors 
    1805             samples[i*nSamples + ndx] = 
    1806               (byte) (Integer.MAX_VALUE - samples[i*nSamples + ndx]); 
    1807           } 
    1808           else if (photoInterp == CFA_ARRAY) { 
     1659            s = (short) (Math.pow(2, bitsPerSample[0]) - 1 - s); 
     1660          } 
     1661 
     1662          if (photoInterp == CFA_ARRAY) { 
    18091663            if (i == 0) { 
    18101664              int pixelIndex = (int) ((row + (count / cw))*imageWidth + col + 
     
    18251679            } 
    18261680          } 
     1681          else { 
     1682            if (i*nSamples + (ndx + 1)*(numBytes + 1) <= samples.length) { 
     1683              DataTools.unpackBytes(s, samples, 
     1684                i*nSamples + ndx*(numBytes + 1), numBytes + 1, littleEndian); 
     1685            } 
     1686          } 
    18271687        } 
    18281688        else if (bps8) { 
     
    18881748          int nioIndex = 
    18891749            numBytes + index < bytes.length ? index : bytes.length - numBytes; 
    1890           short v = nioBytes.getShort(nioIndex); 
     1750          short v = DataTools.bytesToShort(bytes, nioIndex, 2, littleEndian); 
    18911751          index += numBytes; 
    18921752 
  • trunk/loci/formats/codec/PackbitsCodec.java

    r3421 r3900  
    7878        byte n = in.readByte(); 
    7979        if (n >= 0) { // 0 <= n <= 127 
    80           for (int i=0; i<n + 1; i++) { 
    81             output.add(in.readByte()); 
    82           } 
     80          byte[] b = new byte[n + 1]; 
     81          in.read(b); 
     82          output.add(b); 
     83          b = null; 
    8384        } 
    8485        else if (n != -128) { // -127 <= n <= -1 
  • trunk/loci/formats/in/BaseTiffReader.java

    r3881 r3900  
    537537    if (photo == TiffTools.RGB_PALETTE || photo == TiffTools.CFA_ARRAY) { 
    538538      numC = 3; 
    539       bps *= 3; 
    540539    } 
    541540 
     
    575574 
    576575    while (bps % 8 != 0) bps++; 
    577     if (bps == 24 || bps == 48) bps /= 3; 
     576    if (bps == 24) bps = 32; 
    578577 
    579578    if (bitFormat == 3) { 
    580579      core.pixelType[0] = FormatTools.FLOAT; 
    581       //core.littleEndian[0] = true; 
    582580    } 
    583581    else if (bitFormat == 2) { 
  • trunk/loci/formats/in/FV1000Reader.java

    r3854 r3900  
    651651 
    652652    core.rgb[0] = false; 
    653     core.littleEndian[0] = false; 
     653    core.littleEndian[0] = true; 
    654654    core.interleaved[0] = false; 
    655655    core.metadataComplete[0] = true; 
  • trunk/loci/formats/in/OMETiffReader.java

    r3863 r3900  
    325325 
    326326  // -- IFormatReader API methods -- 
     327 
     328  /* @see loci.formats.IFormatReader#fileGroupOption(String) */ 
     329  public int fileGroupOption(String id) throws FormatException, IOException { 
     330    return MUST_GROUP; 
     331  } 
    327332 
    328333  /* @see loci.formats.IFormatReader#isThisType(String, boolean) */ 
     
    525530 
    526531        int sc = core.sizeC[currentSeries]; 
    527         if (core.rgb[currentSeries] && !core.indexed[currentSeries]) sc /= 3; 
     532        if (core.rgb[currentSeries] && !core.indexed[currentSeries]) { 
     533          if (sc <= 3) sc = 1; 
     534          else sc /= 3; 
     535        } 
    528536        core.imageCount[currentSeries] = 
    529537          core.sizeZ[currentSeries] * sc * core.sizeT[currentSeries]; 
  • trunk/loci/formats/in/ZeissLSMReader.java

    r3781 r3900  
    173173    } 
    174174    return swapIfRequired(buf); 
    175   } 
    176  
    177   /* @see loci.formats.IFormatReader#openThumbImage(int) */ 
    178   public BufferedImage openThumbImage(int no) 
    179     throws FormatException, IOException 
    180   { 
    181     FormatTools.assertId(currentId, true, 1); 
    182     FormatTools.checkPlaneNumber(this, no); 
    183  
    184     if (2*no + 1 < ifds.length) return TiffTools.getImage(ifds[2*no + 1], in); 
    185     return super.openThumbImage(no); 
    186175  } 
    187176 
Note: See TracChangeset for help on using the changeset viewer.