Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Png16 #2

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -696,14 +696,16 @@ public boolean hasMasks() {
}
return hasMasks;
}

public BufferedImage openTargetImage() {
return openTargetImage(BufferedImage.TYPE_INT_ARGB);
}
/**
* Opens the target/input image specified by these parameters or
* creates a new (in-memory) image if no input image was specified.
*
* @return {@link BufferedImage} representation of the image.
*/
public BufferedImage openTargetImage() {
public BufferedImage openTargetImage(final int imageType) {

BufferedImage targetImage = null;

Expand All @@ -715,12 +717,13 @@ public BufferedImage openTargetImage() {
final double derivedScale = getScale();
final int targetWidth = (int) (derivedScale * width);
final int targetHeight = (int) (derivedScale * height);
targetImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB);
targetImage = new BufferedImage(targetWidth, targetHeight, imageType);
}

return targetImage;
}


/**
* @return string representation of these parameters (only non-default values are included).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,80 @@ public Response renderTiffImageForBox(@PathParam("owner") final String owner,
}
}

@Path("v1/owner/{owner}/project/{project}/stack/{stack}/z/{z}/box/{x},{y},{width},{height},{scale}/tiff16-image")
@GET
@Produces(RenderServiceUtil.IMAGE_TIFF_MIME_TYPE)
@ApiOperation(
tags = "Bounding Box Image APIs",
value = "Render 16-bit TIFF image for the specified bounding box")
public Response renderTiff16ImageForBox(@PathParam("owner") final String owner,
@PathParam("project") final String project,
@PathParam("stack") final String stack,
@PathParam("x") final Double x,
@PathParam("y") final Double y,
@PathParam("z") final Double z,
@PathParam("width") final Integer width,
@PathParam("height") final Integer height,
@PathParam("scale") final Double scale,
@QueryParam("filter") final Boolean filter,
@QueryParam("binaryMask") final Boolean binaryMask,
@QueryParam("maxTileSpecsToRender") final Integer maxTileSpecsToRender,
@QueryParam("minIntensity") final Double minIntensity,
@QueryParam("maxIntensity") final Double maxIntensity,
@QueryParam("channels") final String channels,
@Context final Request request) {

LOG.info("renderTiffImageForBox: entry");

final ResponseHelper responseHelper = new ResponseHelper(request, getStackMetaData(owner, project, stack));
if (responseHelper.isModified()) {
final RenderParameters renderParameters =
getRenderParametersForGroupBox(owner, project, stack, null,
x, y, z, width, height, scale, filter, binaryMask,
minIntensity, maxIntensity, channels);
return RenderServiceUtil.renderTiffImage(renderParameters, maxTileSpecsToRender, responseHelper, true);
} else {
return responseHelper.getNotModifiedResponse();
}
}

@Path("v1/owner/{owner}/project/{project}/stack/{stack}/z/{z}/box/{x},{y},{width},{height},{scale}/png16-image")
@GET
@Produces(RenderServiceUtil.IMAGE_PNG_MIME_TYPE)
@ApiOperation(
tags = "Bounding Box Image APIs",
value = "Render 16-bit PNG image for the specified bounding box")
public Response renderPng16ImageForBox(@PathParam("owner") final String owner,
@PathParam("project") final String project,
@PathParam("stack") final String stack,
@PathParam("x") final Double x,
@PathParam("y") final Double y,
@PathParam("z") final Double z,
@PathParam("width") final Integer width,
@PathParam("height") final Integer height,
@PathParam("scale") final Double scale,
@QueryParam("filter") final Boolean filter,
@QueryParam("binaryMask") final Boolean binaryMask,
@QueryParam("maxTileSpecsToRender") final Integer maxTileSpecsToRender,
@QueryParam("minIntensity") final Double minIntensity,
@QueryParam("maxIntensity") final Double maxIntensity,
@QueryParam("channels") final String channels,
@Context final Request request) {

LOG.info("renderPngImageForBox: entry");

final ResponseHelper responseHelper = new ResponseHelper(request, getStackMetaData(owner, project, stack));
if (responseHelper.isModified()) {
final RenderParameters renderParameters =
getRenderParametersForGroupBox(owner, project, stack, null,
x, y, z, width, height, scale, filter, binaryMask,
minIntensity, maxIntensity, channels);
return RenderServiceUtil.renderPngImage(renderParameters, maxTileSpecsToRender, responseHelper, true);
} else {
return responseHelper.getNotModifiedResponse();
}
}

@Path("v1/owner/{owner}/project/{project}/stack/{stack}/dvid/imagetile/raw/xy/{width}_{height}/{x}_{y}_{z}/tif")
@GET
@Produces(RenderServiceUtil.IMAGE_TIFF_MIME_TYPE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferUShort;
import java.awt.image.SinglePixelPackedSampleModel;
import java.io.IOException;
import java.io.OutputStream;
Expand Down Expand Up @@ -86,34 +87,60 @@ public static void writePngImage(final BufferedImage bufferedImage,
final OutputStream outputStream)
throws IOException {

if (bufferedImage.getType() != BufferedImage.TYPE_INT_ARGB) {
throw new IOException("invalid image type (" + bufferedImage.getType() +
"), must be BufferedImage.TYPE_INT_ARGB");
}

final ImageInfo imageInfo = new ImageInfo(bufferedImage.getWidth(), bufferedImage.getHeight(), 8, true);

final PngWriter pngWriter = new PngWriter(outputStream, imageInfo);
pngWriter.setCompLevel(compressionLevel);
pngWriter.setFilterType(filterType);
if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) {
// Existing code for TYPE_INT_ARGB
final ImageInfo imageInfo = new ImageInfo(bufferedImage.getWidth(), bufferedImage.getHeight(), 8, true);

final DataBufferInt dataBuffer =((DataBufferInt) bufferedImage.getRaster().getDataBuffer());
if (dataBuffer.getNumBanks() != 1) {
throw new IOException("invalid number of banks (" + dataBuffer.getNumBanks() + "), must be 1");
}
final PngWriter pngWriter = new PngWriter(outputStream, imageInfo);
pngWriter.setCompLevel(compressionLevel);
pngWriter.setFilterType(filterType);

final SinglePixelPackedSampleModel sampleModel = (SinglePixelPackedSampleModel) bufferedImage.getSampleModel();
final ImageLineInt line = new ImageLineInt(imageInfo);
final int[] data = dataBuffer.getData();
for (int row = 0; row < imageInfo.rows; row++) {
int elem = sampleModel.getOffset(0, row);
for (int col = 0; col < imageInfo.cols; col++) {
final int sample = data[elem++];
ImageLineHelper.setPixelRGBA8(line, col, sample);
final DataBufferInt dataBuffer =((DataBufferInt) bufferedImage.getRaster().getDataBuffer());
if (dataBuffer.getNumBanks() != 1) {
throw new IOException("invalid number of banks (" + dataBuffer.getNumBanks() + "), must be 1");
}

final SinglePixelPackedSampleModel sampleModel = (SinglePixelPackedSampleModel) bufferedImage.getSampleModel();
final ImageLineInt line = new ImageLineInt(imageInfo);
final int[] data = dataBuffer.getData();
for (int row = 0; row < imageInfo.rows; row++) {
int elem = sampleModel.getOffset(0, row);
for (int col = 0; col < imageInfo.cols; col++) {
final int sample = data[elem++];
ImageLineHelper.setPixelRGBA8(line, col, sample);
}
pngWriter.writeRow(line, row);
}
pngWriter.end();

} else if (bufferedImage.getType() == BufferedImage.TYPE_USHORT_GRAY) {
// Modified code to avoid "java.awt.image.DataBufferUShort cannot be cast to java.awt.image.DataBufferInt"
final ImageInfo imageInfo = new ImageInfo(bufferedImage.getWidth(), bufferedImage.getHeight(), 16, false, true, false);
final PngWriter pngWriter = new PngWriter(outputStream, imageInfo);
pngWriter.setCompLevel(compressionLevel);
pngWriter.setFilterType(filterType);

final DataBufferUShort dataBuffer = (DataBufferUShort) bufferedImage.getRaster().getDataBuffer();
if (dataBuffer.getNumBanks() != 1) {
throw new IOException("invalid number of banks (" + dataBuffer.getNumBanks() + "), must be 1");
}
pngWriter.writeRow(line, row);

final int [] scanline = new int[imageInfo.cols];
ImageLineInt line = new ImageLineInt(imageInfo, scanline);

for (int row = 0; row < imageInfo.rows; row++) {
for (int col = 0; col < imageInfo.cols; col++) {
scanline[col] = dataBuffer.getData()[row * imageInfo.cols + col];
}
pngWriter.writeRow(line, row);
}
pngWriter.end();
} else {
throw new IOException("invalid image type (" + bufferedImage.getType() +
"), must be BufferedImage.TYPE_INT_ARGB or BufferedImage.TYPE_USHORT_GRAY");
}
pngWriter.end();

// // This looked like a nicer option, but only works for DataBufferByte (not DataBufferInt)
// final ImageLineSetARGBbi lines = new ImageLineSetARGBbi(bufferedImage, imageInfo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.janelia.alignment.ArgbRenderer;
import org.janelia.alignment.BoundingBoxRenderer;
import org.janelia.alignment.RenderParameters;
import org.janelia.alignment.ShortRenderer;
import org.janelia.alignment.Utils;
import org.janelia.render.service.model.IllegalServiceArgumentException;
import org.janelia.render.service.model.ServiceException;
Expand Down Expand Up @@ -78,29 +79,54 @@ public static Response renderJpegImage(final RenderParameters renderParameters,

public static Response renderPngImage(final RenderParameters renderParameters,
final Integer maxTileSpecsToRender,
final ResponseHelper responseHelper) {
final ResponseHelper responseHelper)
{
return renderPngImage(renderParameters, maxTileSpecsToRender, responseHelper, false);

}
public static Response renderPngImage(final RenderParameters renderParameters,
final Integer maxTileSpecsToRender,
final ResponseHelper responseHelper,
final boolean render16bit) {
return renderImageStream(renderParameters,
Utils.PNG_FORMAT,
IMAGE_PNG_MIME_TYPE,
maxTileSpecsToRender,
responseHelper);
responseHelper,
render16bit);
}

public static Response renderTiffImage(final RenderParameters renderParameters,
final Integer maxTileSpecsToRender,
final ResponseHelper responseHelper) {
return renderTiffImage(renderParameters, maxTileSpecsToRender, responseHelper, false);
}

public static Response renderTiffImage(final RenderParameters renderParameters,
final Integer maxTileSpecsToRender,
final ResponseHelper responseHelper,
final boolean render16bit) {
return renderImageStream(renderParameters,
Utils.TIFF_FORMAT,
IMAGE_TIFF_MIME_TYPE,
maxTileSpecsToRender,
responseHelper);
responseHelper,
render16bit);
}

public static Response renderImageStream(final RenderParameters renderParameters,
final String format,
final String mimeType,
final Integer maxTileSpecsToRender,
final ResponseHelper responseHelper) {
return renderImageStream(renderParameters, format, mimeType, maxTileSpecsToRender, responseHelper,false);
}
public static Response renderImageStream(final RenderParameters renderParameters,
final String format,
final String mimeType,
final Integer maxTileSpecsToRender,
final ResponseHelper responseHelper) {
final ResponseHelper responseHelper,
final boolean render16bit) {

LOG.info("renderImageStream: entry, format={}, mimeType={}", format, mimeType);

Expand All @@ -114,7 +140,8 @@ public static Response renderImageStream(final RenderParameters renderParameters
(renderParameters.numberOfTileSpecs() > maxTileSpecsToRender);

final BufferedImage targetImage = validateParametersAndRenderImage(renderParameters,
renderBoundingBoxesOnly);
renderBoundingBoxesOnly,
render16bit);
final BufferedImageStreamingOutput out =
new BufferedImageStreamingOutput(targetImage,
format,
Expand Down Expand Up @@ -149,9 +176,13 @@ public static Response streamImageFile(final File imageFile,

return response;
}

private static BufferedImage validateParametersAndRenderImage(final RenderParameters renderParameters,
final boolean renderBoundingBoxesOnly)
final boolean renderBoundingBoxesOnly){
return validateParametersAndRenderImage(renderParameters, renderBoundingBoxesOnly,false);
}
private static BufferedImage validateParametersAndRenderImage(final RenderParameters renderParameters,
final boolean renderBoundingBoxesOnly,
final boolean render16bit)
throws IllegalArgumentException, IllegalStateException {

LOG.info("validateParametersAndRenderImage: entry, renderParameters={}", renderParameters);
Expand All @@ -160,20 +191,29 @@ private static BufferedImage validateParametersAndRenderImage(final RenderParame
renderParameters.validate();
renderParameters.setNumberOfThreads(1); // service requests should always be single threaded

final BufferedImage targetImage = renderParameters.openTargetImage();
final BufferedImage targetImage;

if (renderBoundingBoxesOnly) {

targetImage = renderParameters.openTargetImage();
final BoundingBoxRenderer boundingBoxRenderer = new BoundingBoxRenderer(renderParameters, Color.GREEN);
boundingBoxRenderer.render(targetImage);

} else {

// otherwise render the real thing ...

ArgbRenderer.render(renderParameters,
targetImage,
SharedImageProcessorCache.getInstance());
if (render16bit) {
targetImage = renderParameters.openTargetImage(BufferedImage.TYPE_USHORT_GRAY);
ShortRenderer.render(renderParameters,
targetImage,
SharedImageProcessorCache.getInstance());
}
else{
targetImage = renderParameters.openTargetImage();
ArgbRenderer.render(renderParameters,
targetImage,
SharedImageProcessorCache.getInstance());
}


}

Expand Down