// we can discard the image from our selection. Also remove any images that
// are wider than the width of the device.
// for (int i = 0; i < images.length; i++) {
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
ImageEncoding encoding = image.getImageEncoding();
if (!supportedEncodings.contains(encoding)) {
if (logger.isDebugEnabled()) {
logger.debug("Discarding variant " + variant +
" as device does not support encoding.");
}
i.remove();
continue;
}
int currentWidth = image.getWidth();
if (currentWidth > deviceWidth) {
if (logger.isDebugEnabled()) {
logger.debug("Discarding variant " + variant +
" - width greater than device width.");
}
i.remove();
continue;
}
}
// If the list is empty then the device does not support any of the
// images in the collection we are testing so we can return null.
if (images.isEmpty()) {
return null;
}
// Remove any images that are wider than the specified widthHint percentage
// of the device width. In this loop we also find the maximum width of all
// the remaining variants.
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
GenericImageSelection generic = (GenericImageSelection)
variant.getSelection();
int widthHint = generic.getWidthHint();
int currentWidth = image.getWidth();
if (widthHint != 0) {
int allowedWidth = (widthHint * deviceWidth) / 100;
if (currentWidth > allowedWidth) {
if (logger.isDebugEnabled()) {
logger.debug("Discarding variant " + variant +
" - width (" + currentWidth +
") greater than " + widthHint +
"% of device width (" + deviceWidth + ")");
}
i.remove();
continue;
}
}
if (currentWidth > maxWidth) {
maxWidth = currentWidth;
}
}
// If the list is empty then the device does not support any of the
// images in the collection we are testing so we can return null.
if (images.isEmpty()) {
return null;
}
// Remove any images that are less than the maximum width as we always want
// to return the largest possible image. Here we also check if any of the
// images' rendering type matches the device.
ImageRendering deviceRenderingMode = device.getRenderMode();
boolean renderingMatch = false;
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
if (image.getWidth() < maxWidth) {
if (logger.isDebugEnabled()) {
logger.debug("Discarding variant " + variant +
" - width less than best width.");
}
i.remove();
continue;
}
if (image.getRendering() == deviceRenderingMode) {
renderingMatch = true;
}
}
// If the list is empty then the device does not support any of the
// images in the collection we are testing so we can return null.
if (images.isEmpty()) {
return null;
}
int devicePixelDepth = device.getPixelDepth();
// there is an image with a pixelDepth => devicePixelDepth
boolean pixelDepthMatch = false;
// there is an image with a pixelDepth of 1 when the device supports better
boolean poorPixelDepthMatch = false;
// there is an image with a pixelDepth greater than that of the device
boolean pixelDepthMismatch = false;
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
if (renderingMatch) {
// If there was at least one rendering match then we remove all those
// images that were not a match.
if (image.getRendering() != deviceRenderingMode) {
if (logger.isDebugEnabled()) {
logger.debug("Discarding variant " + variant +
" - rendering type does not match.");
}
i.remove();
continue;
}
} else {
// If there wasn't any rendering matches then if image encoding is in
// the set JPEG, GIF, PNG, BMP or TIFF it can still be used. Otherwise the
// image is removed.
ImageEncoding currentImageEncoding = image.getImageEncoding();
if (currentImageEncoding != ImageEncoding.JPEG
&& currentImageEncoding != ImageEncoding.GIF
&& currentImageEncoding != ImageEncoding.PNG
&& currentImageEncoding != ImageEncoding.TIFF
&& currentImageEncoding != ImageEncoding.BMP) {
if (logger.isDebugEnabled()) {
logger.debug("Discarding variant " + variant +
" - encoding type does not allow " +
"override of rendering.");
}
i.remove();
continue;
}
}
if (image.getPixelDepth() <= devicePixelDepth) {
if (image.getPixelDepth() == 1 && devicePixelDepth > 1) {
poorPixelDepthMatch = true;
} else {
pixelDepthMatch = true;
}
} else {
pixelDepthMismatch = true;
}
}
// If the list is empty then there wasn't a render match and none
// of the images had an encoding type of JPEG, GIF, PNG, BMP. So we
// can return null as none of the images are suitable.
if (images.isEmpty()) {
return null;
}
// If we didn't match a pixel depth but did find a 1bit image when the
// device supports better, and we don't have anything better, then our
// 1bit image really was our pixelDepthMatch so set the flag to true.
if (!pixelDepthMatch && poorPixelDepthMatch && !pixelDepthMismatch) {
pixelDepthMatch = true;
}
// There was at least one image with a pixel depth within the allowed
// range, so remove all those that have a pixel depth greater than the
// device.
if (pixelDepthMatch) {
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
if (image.getPixelDepth() > devicePixelDepth) {
if (logger.isDebugEnabled()) {
logger.debug("Discarding variant " + variant +
" - pixelDepth less than best available.");
}
i.remove();
continue;
}
}
} else {
// All of the images have a pixel depth greater than the device. However
// we can still use those images in the set JPEG, GIF, PNG, BMP or TIFF. All
// others must be removed
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
ImageEncoding currentImageEncoding = image.getImageEncoding();
if (currentImageEncoding != ImageEncoding.JPEG
&& currentImageEncoding != ImageEncoding.GIF
&& currentImageEncoding != ImageEncoding.PNG
&& currentImageEncoding != ImageEncoding.TIFF
&& currentImageEncoding != ImageEncoding.BMP) {
if (logger.isDebugEnabled()) {
logger.debug("Discarding variant " + variant +
" - pixelDepth too great and" +
" outside of valid set of encodings capable" +
" of reducing in depth.");
}
i.remove();
continue;
}
}
}
// If the list is empty then there wasn't an image with a pixel depth
// less than the device or with an encoding type of JPEG, GIF, PNG, BMP
// or TIFF. So we can return null as none of the images are suitable.
if (images.isEmpty()) {
return null;
} else if (images.size() == 1) {
return (Variant) images.get(0);
}
// Find the best pixelDepth of the remaining images.
// If we had a pixelDepth match then it is simply the largest.
// Otherwise it is the closest above the device pixel depth.
int bestDepth = -1;
if (pixelDepthMatch) {
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
if (image.getPixelDepth() > bestDepth) {
bestDepth = image.getPixelDepth();
}
}
} else {
int bestDiff = 0;
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
int pixelDepth = image.getPixelDepth();
if (pixelDepth == 1) {
if (bestDepth == -1) {
bestDepth = pixelDepth;
}
continue;
}
int diff = pixelDepth - devicePixelDepth;
// make the value absolute;
if (diff < 0) {
diff = 0 - diff;
}
// diff cannot be 0 if we are in this loop because we would have
// matched pixelDepth earlier. So, it is safe to use an initial value
// of zero for bestDiff.
if (bestDiff == 0 || diff < bestDiff) {
bestDiff = diff;
bestDepth = image.getPixelDepth();
}
}
}
Variant imageJPEG = null;
Variant imageGIF = null;
Variant imagePNG = null;
Variant imageTIFF = null;
// Remove those variants with a pixelDepth not equal to the best
for (Iterator i = images.iterator(); i.hasNext();) {
Variant variant = (Variant) i.next();
ImageMetaData image = (ImageMetaData) variant.getMetaData();
if (image.getPixelDepth() != bestDepth) {
i.remove();
}
if (image.getImageEncoding() == ImageEncoding.JPEG) {
imageJPEG = variant;
} else if (image.getImageEncoding() == ImageEncoding.GIF) {
imageGIF = variant;
} else if (image.getImageEncoding() == ImageEncoding.PNG) {
imagePNG = variant;
} else if (image.getImageEncoding() == ImageEncoding.TIFF) {
imageTIFF = variant;
}
}
if (images.size() == 1) {