use of org.haiku.haikudepotserver.dataobjects.PkgScreenshotImage in project haikudepotserver by haiku.
the class PkgScreenshotServiceImpl method storePkgScreenshotImage.
/**
* <p>Note that if the screenshot is already stored then this method will simply return that screenshot.</p>
*
* @param ordering can be NULL; in which case the screenshot will come at the end.
*/
@Override
public PkgScreenshot storePkgScreenshotImage(InputStream input, ObjectContext context, PkgSupplement pkgSupplement, Integer ordering) throws IOException, BadPkgScreenshotException {
Preconditions.checkArgument(null != input, "the input must be provided");
Preconditions.checkArgument(null != context, "the context must be provided");
Preconditions.checkArgument(null != pkgSupplement, "the pkg supplement must be provided");
byte[] pngData = ByteStreams.toByteArray(new BoundedInputStream(input, SCREENSHOT_SIZE_LIMIT));
ImageHelper.Size size = imageHelper.derivePngSize(pngData);
String hashSha256 = HASH_FUNCTION.hashBytes(pngData).toString();
if (null == size) {
LOGGER.warn("attempt to store a screenshot image that is not a png");
throw new BadPkgScreenshotException();
}
if (size.height > SCREENSHOT_SIDE_LIMIT || size.width > SCREENSHOT_SIDE_LIMIT) {
LOGGER.warn("attempt to store a screenshot image that is too large; " + size.toString());
throw new BadPkgScreenshotException();
}
for (PkgScreenshot pkgScreenshot : pkgSupplement.getPkgScreenshots()) {
if (pkgScreenshot.getHashSha256().equals(hashSha256)) {
LOGGER.warn("attempt to store a screenshot image that is already stored for this package");
return pkgScreenshot;
}
}
MediaType png = MediaType.tryGetByCode(context, com.google.common.net.MediaType.PNG.toString()).get();
// now we need to know the largest ordering so we can add this one at the end of the orderings
// such that it is the next one in the list.
int actualOrdering = null == ordering ? pkgSupplement.getHighestPkgScreenshotOrdering().orElse(0) + 1 : ordering;
PkgScreenshot screenshot = context.newObject(PkgScreenshot.class);
screenshot.setCode(UUID.randomUUID().toString());
screenshot.setOrdering(actualOrdering);
screenshot.setHeight(size.height);
screenshot.setWidth(size.width);
screenshot.setLength(pngData.length);
screenshot.setHashSha256(hashSha256);
pkgSupplement.addToManyTarget(PkgSupplement.PKG_SCREENSHOTS.getName(), screenshot, true);
PkgScreenshotImage screenshotImage = context.newObject(PkgScreenshotImage.class);
screenshotImage.setMediaType(png);
screenshotImage.setData(pngData);
screenshot.addToManyTarget(PkgScreenshot.PKG_SCREENSHOT_IMAGES.getName(), screenshotImage, true);
pkgSupplement.setModifyTimestamp();
LOGGER.info("a screenshot #{} has been added to package [{}] ({})", actualOrdering, pkgSupplement.getBasePkgName(), screenshot.getCode());
return screenshot;
}
use of org.haiku.haikudepotserver.dataobjects.PkgScreenshotImage in project haikudepotserver by haiku.
the class PkgScreenshotServiceImpl method writePkgScreenshotImage.
/**
* <p>This method will write the package's screenshot to the output stream. It will constrain the output to the
* size given by scaling the image. The output is a PNG image.</p>
*/
@Override
public void writePkgScreenshotImage(OutputStream output, ObjectContext context, PkgScreenshot screenshot, int targetWidth, int targetHeight) throws IOException {
Preconditions.checkArgument(null != output, "the output stream must be provided");
Preconditions.checkArgument(null != context, "the context must be provided");
Preconditions.checkArgument(null != screenshot, "the screenshot must be provided");
Preconditions.checkArgument(targetHeight > 0, "the target height is <= 0");
Preconditions.checkArgument(targetWidth > 0, "the target width is <= 0");
Optional<PkgScreenshotImage> pkgScreenshotImageOptional = screenshot.tryGetPkgScreenshotImage();
if (!pkgScreenshotImageOptional.isPresent()) {
throw new IllegalStateException("the screenshot " + screenshot.getCode() + " is missing a screenshot image");
}
if (!pkgScreenshotImageOptional.get().getMediaType().getCode().equals(com.google.common.net.MediaType.PNG.toString())) {
throw new IllegalStateException("the screenshot system only supports png images at the present time");
}
byte[] data = pkgScreenshotImageOptional.get().getData();
ImageHelper.Size size = imageHelper.derivePngSize(data);
// check to see if the screenshot needs to be resized to fit.
if (size.width > targetWidth || size.height > targetHeight) {
ByteArrayInputStream imageInputStream = new ByteArrayInputStream(data);
BufferedImage bufferedImage = ImageIO.read(imageInputStream);
BufferedImage scaledBufferedImage = Scalr.resize(bufferedImage, targetWidth, targetHeight);
ImageIO.write(scaledBufferedImage, "png", output);
} else {
output.write(data);
}
}
use of org.haiku.haikudepotserver.dataobjects.PkgScreenshotImage in project haikudepotserver by haiku.
the class PkgScreenshotServiceImpl method optimizeScreenshot.
@Override
public boolean optimizeScreenshot(ObjectContext context, PkgScreenshot screenshot) throws IOException {
if (!pngOptimizationService.identityOptimization()) {
PkgScreenshotImage pkgScreenshotImage = screenshot.tryGetPkgScreenshotImage().get();
if (pkgScreenshotImage.getMediaType().getCode().equals(com.google.common.net.MediaType.PNG.withoutParameters().toString())) {
byte[] originalImageData = pkgScreenshotImage.getData();
byte[] optimizedData = pngOptimizationService.optimize(originalImageData);
if (optimizedData.length < originalImageData.length) {
pkgScreenshotImage.setData(optimizedData);
screenshot.setLength(optimizedData.length);
screenshot.setModifyTimestamp();
screenshot.setHashSha256(HASH_FUNCTION.hashBytes(optimizedData).toString());
LOGGER.debug("did store optimized image for pkg screenshot [{}]", screenshot.getCode());
return true;
} else {
LOGGER.warn("optimized data is larger than the original data for pkg screenshot [{}]", screenshot.getCode());
}
} else {
LOGGER.warn("pkg screenshot '{}' in unknown image format '{}'; will ignore", screenshot.getCode(), pkgScreenshotImage.getMediaType().getCode());
}
} else {
LOGGER.warn("skipping identity optimization for screenshot [{}]", screenshot.getCode());
}
return false;
}
use of org.haiku.haikudepotserver.dataobjects.PkgScreenshotImage in project haikudepotserver by haiku.
the class PkgScreenshotImportArchiveJobRunner method generateHashCode.
private HashCode generateHashCode(String pkgScreenshotCode) {
ObjectContext context = serverRuntime.newContext();
PkgScreenshot pkgScreenshot = PkgScreenshot.getByCode(context, pkgScreenshotCode);
PkgScreenshotImage pkgScreenshotImage = pkgScreenshot.getPkgScreenshotImage();
return HASH_FUNCTION.hashBytes(pkgScreenshotImage.getData());
}
Aggregations