private BufferedImage windowMonochrome( ImageListViewCell displayedCell, BufferedImage srcImg, float windowLocation, float windowWidth) { BufferedImage destImg = new BufferedImage(srcImg.getWidth(), srcImg.getHeight(), BufferedImage.TYPE_INT_RGB); boolean isSigned = false; int minValue = 0; { // hack: try to determine signedness and minValue from DICOM metadata if available -- // the BufferedImage's metadata don't contain that information reliably. // Only works for some special cases ImageListViewModelElement elt = displayedCell.getDisplayedModelElement(); if (elt instanceof DicomImageListViewModelElement) { DicomImageListViewModelElement delt = (DicomImageListViewModelElement) elt; DicomObject imgMetadata = delt.getDicomImageMetaData(); int bitsAllocated = imgMetadata.getInt(Tag.BitsAllocated); isSigned = (1 == imgMetadata.getInt(Tag.PixelRepresentation)); if (isSigned && (bitsAllocated > 0)) { minValue = -(1 << (bitsAllocated - 1)); } } } final int windowedImageGrayscalesCount = 256; // for BufferedImage.TYPE_INT_RGB float scale = windowedImageGrayscalesCount / windowWidth; float offset = (windowWidth / 2 - windowLocation) * scale; if (!(srcImg.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_GRAY)) { throw new IllegalArgumentException("source image must be grayscales"); } Raster srcRaster = srcImg.getRaster(); if (srcRaster.getNumBands() != 1) { throw new IllegalArgumentException( "grayscale source image must have one color band, but has " + srcRaster.getNumBands() + "??"); } WritableRaster resultRaster = destImg.getRaster(); for (int x = 0; x < srcImg.getWidth(); x++) { for (int y = 0; y < srcImg.getHeight(); y++) { int srcGrayValue = srcRaster.getSample(x, y, 0); if (isSigned) { srcGrayValue = (int) (short) srcGrayValue; // will only work for 16-bit signed... } float destGrayValue = scale * srcGrayValue + offset; // clamp if (destGrayValue < 0) { destGrayValue = 0; } else if (destGrayValue >= windowedImageGrayscalesCount) { destGrayValue = windowedImageGrayscalesCount - 1; } resultRaster.setSample(x, y, 0, destGrayValue); resultRaster.setSample(x, y, 1, destGrayValue); resultRaster.setSample(x, y, 2, destGrayValue); } } return destImg; }
@Override public void onDimseRSP(Association as, DicomObject cmd, DicomObject data) { int status = cmd.getInt(Tag.Status); switch (status) { case 0: { LOG.debug("Dataset stored at {}", as.getCalledAET()); break; } case 0xA700: { LOG.error( "Failed to store dataset - Out Of Resources! (status: {}H, calledAET:{}, comment:{})", new Object[] { StringUtils.shortToHex(status), as.getCalledAET(), cmd.getString(Tag.ErrorComment) }); break; } case 0xA900: { LOG.error( "Failed to store dataset - Dataset doesn't match SOP class! (status: {}H, calledAET:{}, comment:{})", new Object[] { StringUtils.shortToHex(status), as.getCalledAET(), cmd.getString(Tag.ErrorComment) }); break; } case 0xC000: { LOG.error( "Failed to store dataset - Can't understand! (status: {}H, calledAET:{}, comment:{})", new Object[] { StringUtils.shortToHex(status), as.getCalledAET(), cmd.getString(Tag.ErrorComment) }); break; } case 0xB000: case 0xB006: case 0xB007: LOG.warn( "Dataset stored at {} with status {}H", as.getCalledAET(), StringUtils.shortToHex(status)); break; default: LOG.error( "Failed to store dataset! (status: {}H, calledAET:{}, comment:{})", new Object[] { StringUtils.shortToHex(status), as.getCalledAET(), cmd.getString(Tag.ErrorComment) }); } }
@Override public void onDimseRSP(Association as, DicomObject cmd, DicomObject data) { int status = cmd.getInt(Tag.Status); switch (status) { case 0x0000: case 0x0001: case 0x0002: case 0x0003: break; case 0x0116: LOG.warn( "Received Warning Status 116H (=Attribute Value Out of Range) from remote AE {}", as.getCalledAET()); break; default: LOG.error( "Sending IAN(SCN) failed with status {}H at calledAET:{}", StringUtils.shortToHex(status), as.getCalledAET()); } }