Search in sources :

Example 11 with UnsupportedCompressionException

use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.

the class DicomReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);
    in = new RandomAccessInputStream(id);
    in.order(true);
    CoreMetadata m = core.get(0);
    // look for companion files
    attachCompanionFiles();
    helper = new DicomReader();
    helper.setGroupFiles(false);
    m.littleEndian = true;
    location = 0;
    isJPEG = false;
    isRLE = false;
    bigEndianTransferSyntax = false;
    oddLocations = false;
    inSequence = false;
    bitsPerPixel = 0;
    elementLength = 0;
    vr = 0;
    lut = null;
    offsets = null;
    inverted = false;
    // some DICOM files have a 128 byte header followed by a 4 byte identifier
    LOGGER.info("Verifying DICOM format");
    MetadataLevel level = getMetadataOptions().getMetadataLevel();
    in.seek(128);
    if (in.readString(4).equals("DICM")) {
        if (level != MetadataLevel.MINIMUM) {
            // header exists, so we'll read it
            in.seek(0);
            addSeriesMeta("Header information", in.readString(128));
            in.skipBytes(4);
        }
        location = 128;
    } else
        in.seek(0);
    LOGGER.info("Reading tags");
    long baseOffset = 0;
    boolean decodingTags = true;
    boolean signed = false;
    String currentType = "";
    while (decodingTags) {
        if (in.getFilePointer() + 4 >= in.length()) {
            break;
        }
        LOGGER.debug("Reading tag from {}", in.getFilePointer());
        int tag = getNextTag(in);
        if (elementLength <= 0)
            continue;
        oddLocations = (location & 1) != 0;
        LOGGER.debug("  tag={} len={} fp=", new Object[] { tag, elementLength, in.getFilePointer() });
        String s = null;
        switch(tag) {
            case TRANSFER_SYNTAX_UID:
                // this tag can indicate which compression scheme is used
                s = in.readString(elementLength);
                addInfo(tag, s);
                if (s.startsWith("1.2.840.10008.1.2.4.9"))
                    isJP2K = true;
                else if (s.startsWith("1.2.840.10008.1.2.4"))
                    isJPEG = true;
                else if (s.startsWith("1.2.840.10008.1.2.5"))
                    isRLE = true;
                else if (s.equals("1.2.8.10008.1.2.1.99"))
                    isDeflate = true;
                else if (s.indexOf("1.2.4") > -1 || s.indexOf("1.2.5") > -1) {
                    throw new UnsupportedCompressionException("Sorry, compression type " + s + " not supported");
                }
                if (s.indexOf("1.2.840.10008.1.2.2") >= 0) {
                    bigEndianTransferSyntax = true;
                }
                break;
            case NUMBER_OF_FRAMES:
                s = in.readString(elementLength);
                addInfo(tag, s);
                double frames = Double.parseDouble(s);
                if (frames > 1.0)
                    imagesPerFile = (int) frames;
                break;
            case SAMPLES_PER_PIXEL:
                addInfo(tag, in.readShort());
                break;
            case PLANAR_CONFIGURATION:
                int config = in.readShort();
                m.interleaved = config == 0;
                addInfo(tag, config);
                break;
            case ROWS:
                int y = in.readShort();
                if (y > getSizeY()) {
                    m.sizeY = y;
                }
                addInfo(tag, getSizeY());
                break;
            case COLUMNS:
                int x = in.readShort();
                if (x > getSizeX()) {
                    m.sizeX = x;
                }
                addInfo(tag, getSizeX());
                break;
            case PHOTOMETRIC_INTERPRETATION:
            case PIXEL_SPACING:
            case SLICE_SPACING:
            case RESCALE_INTERCEPT:
            case WINDOW_CENTER:
                String winCenter = in.readString(elementLength);
                if (winCenter.trim().length() == 0)
                    centerPixelValue = -1;
                else {
                    try {
                        centerPixelValue = new Double(winCenter).intValue();
                    } catch (NumberFormatException e) {
                        centerPixelValue = -1;
                    }
                }
                addInfo(tag, winCenter);
                break;
            case RESCALE_SLOPE:
                addInfo(tag, in.readString(elementLength));
                break;
            case BITS_ALLOCATED:
                if (bitsPerPixel == 0)
                    bitsPerPixel = in.readShort();
                else
                    in.skipBytes(2);
                addInfo(tag, bitsPerPixel);
                break;
            case PIXEL_REPRESENTATION:
            case PIXEL_SIGN:
                short ss = in.readShort();
                signed = ss == 1;
                addInfo(tag, ss);
                break;
            case 537262910:
            case WINDOW_WIDTH:
                String t = in.readString(elementLength);
                if (t.trim().length() == 0)
                    maxPixelRange = -1;
                else {
                    try {
                        maxPixelRange = new Double(t.trim()).intValue();
                    } catch (NumberFormatException e) {
                        maxPixelRange = -1;
                    }
                }
                addInfo(tag, t);
                break;
            case PIXEL_DATA:
            case ITEM:
            case 0xffee000:
                if (elementLength != 0) {
                    baseOffset = in.getFilePointer();
                    addInfo(tag, location);
                    decodingTags = false;
                } else
                    addInfo(tag, null);
                break;
            case 0x7f880010:
                if (elementLength != 0) {
                    baseOffset = location + 4;
                    decodingTags = false;
                }
                break;
            case 0x7fe00000:
                in.skipBytes(elementLength);
                break;
            case 0:
                in.seek(in.getFilePointer() - 4);
                break;
            case 0x41430:
                currentType = getHeaderInfo(tag, s).trim();
                break;
            case 0x41500:
                if (currentType.equals("IMAGE")) {
                    if (fileList == null) {
                        fileList = new HashMap<Integer, List<String>>();
                    }
                    int seriesIndex = 0;
                    if (originalInstance != null) {
                        try {
                            seriesIndex = Integer.parseInt(originalInstance);
                        } catch (NumberFormatException e) {
                            LOGGER.debug("Could not parse instance number: {}", originalInstance);
                        }
                    }
                    if (fileList.get(seriesIndex) == null) {
                        fileList.put(seriesIndex, new ArrayList<String>());
                    }
                    fileList.get(seriesIndex).add(getHeaderInfo(tag, s).trim());
                } else {
                    companionFiles.add(getHeaderInfo(tag, s).trim());
                }
                currentType = "";
                break;
            default:
                long oldfp = in.getFilePointer();
                addInfo(tag, s);
                in.seek(oldfp + elementLength);
        }
        if (in.getFilePointer() >= (in.length() - 4)) {
            decodingTags = false;
        }
    }
    if (imagesPerFile == 0)
        imagesPerFile = 1;
    if (id.endsWith("DICOMDIR")) {
        String parent = new Location(currentId).getAbsoluteFile().getParent();
        for (int q = 0; q < fileList.size(); q++) {
            Integer[] fileKeys = fileList.keySet().toArray(new Integer[0]);
            for (int i = 0; i < fileList.get(fileKeys[q]).size(); i++) {
                String file = fileList.get(fileKeys[q]).get(i);
                file = file.replace('\\', File.separatorChar);
                file = file.replaceAll("/", File.separator);
                fileList.get(fileKeys[q]).set(i, parent + File.separator + file);
            }
        }
        for (int i = 0; i < companionFiles.size(); i++) {
            String file = companionFiles.get(i);
            file = file.replace('\\', File.separatorChar);
            file = file.replaceAll("/", File.separator);
            companionFiles.set(i, parent + File.separator + file);
        }
        companionFiles.add(new Location(currentId).getAbsolutePath());
        initFile(fileList.get(0).get(0));
        return;
    }
    m.bitsPerPixel = bitsPerPixel;
    while (bitsPerPixel % 8 != 0) bitsPerPixel++;
    if (bitsPerPixel == 24 || bitsPerPixel == 48) {
        bitsPerPixel /= 3;
        m.bitsPerPixel /= 3;
    }
    m.pixelType = FormatTools.pixelTypeFromBytes(bitsPerPixel / 8, signed, false);
    int bpp = FormatTools.getBytesPerPixel(getPixelType());
    int plane = getSizeX() * getSizeY() * (lut == null ? getSizeC() : 1) * bpp;
    LOGGER.info("Calculating image offsets");
    // calculate the offset to each plane
    in.seek(baseOffset - 12);
    int len = in.readInt();
    if (len >= 0 && len + in.getFilePointer() < in.length()) {
        in.skipBytes(len);
        int check = in.readShort() & 0xffff;
        if (check == 0xfffe) {
            baseOffset = in.getFilePointer() + 2;
        }
    }
    offsets = new long[imagesPerFile];
    for (int i = 0; i < imagesPerFile; i++) {
        if (isRLE) {
            if (i == 0)
                in.seek(baseOffset);
            else {
                in.seek(offsets[i - 1]);
                CodecOptions options = new CodecOptions();
                options.maxBytes = plane / bpp;
                for (int q = 0; q < bpp; q++) {
                    new PackbitsCodec().decompress(in, options);
                    while (in.read() == 0) ;
                    in.seek(in.getFilePointer() - 1);
                }
            }
            in.skipBytes(i == 0 ? 64 : 53);
            while (in.read() == 0) ;
            offsets[i] = in.getFilePointer() - 1;
        } else if (isJPEG || isJP2K) {
            // scan for next JPEG magic byte sequence
            if (i == 0)
                offsets[i] = baseOffset;
            else
                offsets[i] = offsets[i - 1] + 3;
            byte secondCheck = isJPEG ? (byte) 0xd8 : (byte) 0x4f;
            in.seek(offsets[i]);
            byte[] buf = new byte[8192];
            int n = in.read(buf);
            boolean found = false;
            while (!found) {
                for (int q = 0; q < n - 2; q++) {
                    if (buf[q] == (byte) 0xff && buf[q + 1] == secondCheck && buf[q + 2] == (byte) 0xff) {
                        if (isJPEG || (isJP2K && buf[q + 3] == 0x51)) {
                            found = true;
                            offsets[i] = in.getFilePointer() + q - n;
                            break;
                        }
                    }
                }
                if (!found) {
                    for (int q = 0; q < 4; q++) {
                        buf[q] = buf[buf.length + q - 4];
                    }
                    n = in.read(buf, 4, buf.length - 4) + 4;
                }
            }
        } else
            offsets[i] = baseOffset + plane * i;
    }
    makeFileList();
    LOGGER.info("Populating metadata");
    int seriesCount = fileList.size();
    Integer[] keys = fileList.keySet().toArray(new Integer[0]);
    Arrays.sort(keys);
    if (seriesCount > 1) {
        core.clear();
    }
    for (int i = 0; i < seriesCount; i++) {
        if (seriesCount == 1) {
            CoreMetadata ms = core.get(i);
            ms.sizeZ = imagesPerFile * fileList.get(keys[i]).size();
            if (ms.sizeC == 0)
                ms.sizeC = 1;
            ms.rgb = ms.sizeC > 1;
            ms.sizeT = 1;
            ms.dimensionOrder = "XYCZT";
            ms.metadataComplete = true;
            ms.falseColor = false;
            if (isRLE)
                core.get(i).interleaved = false;
            ms.imageCount = ms.sizeZ;
        } else {
            helper.close();
            helper.setId(fileList.get(keys[i]).get(0));
            CoreMetadata ms = helper.getCoreMetadataList().get(0);
            ms.sizeZ *= fileList.get(keys[i]).size();
            ms.imageCount = ms.sizeZ;
            core.add(ms);
        }
    }
    // The metadata store we're working with.
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this, true);
    String stamp = null;
    if (date != null && time != null) {
        stamp = date + " " + time;
        stamp = DateTools.formatDate(stamp, "yyyy.MM.dd HH:mm:ss", ".");
    }
    if (stamp == null || stamp.trim().equals(""))
        stamp = null;
    for (int i = 0; i < core.size(); i++) {
        if (stamp != null)
            store.setImageAcquisitionDate(new Timestamp(stamp), i);
        store.setImageName("Series " + i, i);
    }
    if (level != MetadataLevel.MINIMUM) {
        for (int i = 0; i < core.size(); i++) {
            store.setImageDescription(imageType, i);
            // all physical sizes were stored in mm, so must be converted to um
            if (pixelSizeX != null) {
                Length x = FormatTools.getPhysicalSizeX(new Double(pixelSizeX), UNITS.MILLIMETER);
                if (x != null) {
                    store.setPixelsPhysicalSizeX(x, i);
                }
            }
            if (pixelSizeY != null) {
                Length y = FormatTools.getPhysicalSizeY(new Double(pixelSizeY), UNITS.MILLIMETER);
                if (y != null) {
                    store.setPixelsPhysicalSizeY(y, i);
                }
            }
            if (pixelSizeZ != null) {
                Length z = FormatTools.getPhysicalSizeZ(new Double(pixelSizeZ), UNITS.MILLIMETER);
                if (z != null) {
                    store.setPixelsPhysicalSizeZ(z, i);
                }
            }
            for (int p = 0; p < getImageCount(); p++) {
                if (p < positionX.size()) {
                    if (positionX.get(p) != null) {
                        Length x = new Length(positionX.get(p), UNITS.MM);
                        if (x != null) {
                            store.setPlanePositionX(x, 0, p);
                        }
                    }
                }
                if (p < positionY.size()) {
                    if (positionY.get(p) != null) {
                        Length y = new Length(positionY.get(p), UNITS.MM);
                        if (y != null) {
                            store.setPlanePositionY(y, 0, p);
                        }
                    }
                }
                if (p < positionZ.size()) {
                    if (positionZ.get(p) != null) {
                        Length z = new Length(positionZ.get(p), UNITS.MM);
                        if (z != null) {
                            store.setPlanePositionZ(z, 0, p);
                        }
                    }
                }
            }
        }
    }
}
Also used : CodecOptions(loci.formats.codec.CodecOptions) UnsupportedCompressionException(loci.formats.UnsupportedCompressionException) CoreMetadata(loci.formats.CoreMetadata) Timestamp(ome.xml.model.primitives.Timestamp) PackbitsCodec(loci.formats.codec.PackbitsCodec) MetadataStore(loci.formats.meta.MetadataStore) Length(ome.units.quantity.Length) ArrayList(java.util.ArrayList) List(java.util.List) RandomAccessInputStream(loci.common.RandomAccessInputStream) Location(loci.common.Location)

Example 12 with UnsupportedCompressionException

use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.

the class LIMReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);
    in = new RandomAccessInputStream(id);
    CoreMetadata m = core.get(0);
    m.littleEndian = true;
    in.order(isLittleEndian());
    m.sizeX = in.readShort() & 0x7fff;
    m.sizeY = in.readShort();
    int bits = in.readShort();
    while (bits % 8 != 0) bits++;
    if ((bits % 3) == 0) {
        m.sizeC = 3;
        bits /= 3;
    }
    m.pixelType = FormatTools.pixelTypeFromBytes(bits / 8, false, false);
    isCompressed = in.readShort() != 0;
    addGlobalMeta("Is compressed", isCompressed);
    if (isCompressed) {
        throw new UnsupportedCompressionException("Compressed LIM files not supported.");
    }
    m.imageCount = 1;
    m.sizeZ = 1;
    m.sizeT = 1;
    if (getSizeC() == 0)
        m.sizeC = 1;
    m.rgb = getSizeC() > 1;
    m.dimensionOrder = "XYZCT";
    m.indexed = false;
    m.falseColor = false;
    m.interleaved = true;
    m.metadataComplete = true;
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this);
}
Also used : MetadataStore(loci.formats.meta.MetadataStore) UnsupportedCompressionException(loci.formats.UnsupportedCompressionException) RandomAccessInputStream(loci.common.RandomAccessInputStream) CoreMetadata(loci.formats.CoreMetadata)

Aggregations

UnsupportedCompressionException (loci.formats.UnsupportedCompressionException)12 RandomAccessInputStream (loci.common.RandomAccessInputStream)6 CoreMetadata (loci.formats.CoreMetadata)5 CodecOptions (loci.formats.codec.CodecOptions)4 JPEGCodec (loci.formats.codec.JPEGCodec)3 MetadataStore (loci.formats.meta.MetadataStore)3 ArrayList (java.util.ArrayList)2 Location (loci.common.Location)2 PackbitsCodec (loci.formats.codec.PackbitsCodec)2 Length (ome.units.quantity.Length)2 FileInputStream (java.io.FileInputStream)1 List (java.util.List)1 GZIPInputStream (java.util.zip.GZIPInputStream)1 InflaterInputStream (java.util.zip.InflaterInputStream)1 FormatException (loci.formats.FormatException)1 Codec (loci.formats.codec.Codec)1 JPEG2000Codec (loci.formats.codec.JPEG2000Codec)1 MJPBCodec (loci.formats.codec.MJPBCodec)1 MJPBCodecOptions (loci.formats.codec.MJPBCodecOptions)1 MSRLECodec (loci.formats.codec.MSRLECodec)1