|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objectorg.hd.d.pg2k.svrCore.MIME.AbstractHandler
org.hd.d.pg2k.svrCore.MIME.AbstractImageHandler
public abstract class AbstractImageHandler
Base class with useful default behaviour for image exhibit media-handler classes. By default this uses ImageIO (iio) routines to extract an image and metadata from an exhibit stream, and will allow the generation of thumbnails if an encoder and thumbnail parameters can be found at run-time.
Various routines can be overridden in deriving classes to change this behaviour.
Potentially-memory-intensive routines may be synchronised in this class (on a private lock) in order to reduce the chance of blowing up the VM by accident, but not if this may cause deadlock elsewhere.
| Nested Class Summary |
|---|
| Nested classes/interfaces inherited from interface org.hd.d.pg2k.svrCore.MIME.Handler |
|---|
Handler.ThumbnailParams |
| Field Summary | |
|---|---|
private static java.util.concurrent.atomic.AtomicReferenceArray<java.lang.Boolean> |
encoderExists
Thread-safe bounded-size cache for canMakeThumbnails() and _getEncoder() as to whether an encoder can be created; never null. |
private static boolean |
ONLY_GET_STD_METADATA
If true, only get "standard" (lossy) metadata to save space. |
private static java.lang.String |
STD_METADATA_FORMAT_NAME
Standard metadata format name. |
private static int |
THUMBNAIL_SIZE_TOL
Image size tolerance as a fraction of the target size; strictly positive. |
private static int |
TRIM_CHILDREN_MAX
Maximum number of children of a single node before culling/trimming it; strictly positive. |
private static boolean |
TRIM_METADATA
If true, trim bulky and not-very-useful metadata (eg palette entries). |
| Fields inherited from interface org.hd.d.pg2k.svrCore.MIME.Handler |
|---|
TAG_NAME_METADATA_TOP |
| Constructor Summary | |
|---|---|
AbstractImageHandler()
|
|
| Method Summary | |
|---|---|
protected javax.imageio.ImageWriter |
_getEncoder()
Gets an encoder/writer for this image type if one is available, else returns null. |
protected int |
_reduceColoursQualityThreshold()
Guide colour-reduction to reduce quality and size of lossless image formats. |
protected void |
_trimMetadata(org.w3c.dom.Node n,
Name.ExhibitFull exhibitName)
Removes bulky and not-very-useful metadata sub-trees from below the given node. |
boolean |
canMakeThumbnails()
Claim that we can make thumbnails for this image type if we can find parameters and an encoder at run-time. |
java.awt.image.BufferedImage |
decodeImage(java.io.InputStream is)
Decode image using generic image IO routines; null if cannot be done. |
protected int |
estimateWorkingMemoryToCreateThumbnails(java.awt.Dimension xyDim)
Estimates bytes of working memory required to create thumbnails for an image. |
protected org.w3c.dom.Node |
extractSpecificImageMetaData(javax.imageio.metadata.IIOMetadata imageMetadata,
Name.ExhibitFull exhibitName)
Get specific (image) metadata for one particular image type; null if none. |
java.awt.Dimension |
get2DImageDimensions(java.io.InputStream is)
Get dimensions X and Y of an image by decoding entire image, else null if dimensions cannot be computed. |
org.w3c.dom.Node |
getMetadata(java.io.InputStream is,
Name.ExhibitFull exhibitName)
Gets all available exhibit metadata as a single XML DOM tree; null if none. |
byte[] |
makeImageBinary(java.awt.image.BufferedImage imageIn,
int quality)
Creates output file-formatted; null for a permanent failure. |
byte[] |
makeSizeConstrainedEncodedImage(int lowerQualityBound,
int initialQualityHint,
int upperQualityBound,
java.awt.image.BufferedImage inputImage,
int targetMin,
int targetMax,
int absMinSize,
int absMaxSize,
int targetBytes)
Make a byte[]-encoded image of this type constained above and below by size; null if not possible. |
protected byte[] |
makeThumbnailImage(java.awt.image.BufferedImage imageIn,
boolean std,
int minSize,
int maxSize)
Return individual thumbnail image as file-format byte array in same format as original; null if not possible. |
ExhibitThumbnails |
makeThumbnails(ExhibitStaticAttr esa,
AllExhibitProperties.ExhibitDataSource eds,
AllExhibitProperties aep,
boolean unlimitedResources)
Make thumbnails/samples for the specified exhibit; null if thumbnails cannot (currently) be made. |
ExhibitThumbnails |
makeThumbnails(java.io.InputStream is,
long originalLength)
Make thumbnails/samples for the specified exhibit; null if thumbnails cannot (currently) be made. |
private static void |
setJAICacheParams()
Set/reset JAI cache/memory parameters. |
| Methods inherited from class org.hd.d.pg2k.svrCore.MIME.AbstractHandler |
|---|
getThumbnailParams |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Methods inherited from interface org.hd.d.pg2k.svrCore.MIME.Handler |
|---|
getExhibitType |
| Field Detail |
|---|
private static final int THUMBNAIL_SIZE_TOL
The larger this number the tighter in conformance to the target size the final image will have to be, which will make convergence take longer or in extreme cases prevent generation of a thumbnail altogether.
A reasonable value for this is probably in the region 3--50.
private static final boolean ONLY_GET_STD_METADATA
private static final java.lang.String STD_METADATA_FORMAT_NAME
private static final boolean TRIM_METADATA
private static final int TRIM_CHILDREN_MAX
private static final java.util.concurrent.atomic.AtomicReferenceArray<java.lang.Boolean> encoderExists
Updated by _getEncoder() but also used by canMakeThumbnails() to avoid calling _getEncoder() if possible for speed and to save possible resource leaks.
This size of this is limited by the number of exhibit types we support.
| Constructor Detail |
|---|
public AbstractImageHandler()
| Method Detail |
|---|
public ExhibitThumbnails makeThumbnails(java.io.InputStream is,
long originalLength)
throws java.io.IOException
If this wishes to indicate that it cannot ever make one or more thumbnails/samples for a given exhibit then this should return a ExhibitThumbnails object with one or both thumbnails set to null.
(If canMakeThumbnails() returns false, this should return null.)
This does not close its input stream when done.
This will only work correctly if the exhibit is of the correct type, eg its magic number must already have been tested.
This assumes enough memory and other resource is available.
By default, returns null, ie thumbnails cannot be made now.
Sophisticated handlers may wish to override this.
Whatever thumbnails are returned, any small thumbnail is smaller than any standard thumbnail, and any standard thumbnail is smaller than the original.
makeThumbnails in interface HandlermakeThumbnails in class AbstractHandleris - the whole raw image positioned at its startoriginalLength - is the length of the encoded original in bytes;
always positive and must reflect the stream input
and will be constrained to Integer.MAX_VALUE if larger
java.io.IOException
public final ExhibitThumbnails makeThumbnails(ExhibitStaticAttr esa,
AllExhibitProperties.ExhibitDataSource eds,
AllExhibitProperties aep,
boolean unlimitedResources)
throws java.io.IOException
This may fail with an IOException or return null to indicate that it is currently unable to create thumbnails/samples (though this condition may be temporary).
If this wishes to indicate that it cannot make one or more thumbnails/samples for a given exhibit then this should return a ExhibitThumbnails object with one or both thumbnails set to null.
(If canMakeThumbnails() returns false, this should return null.)
By default, returns null, ie thumbnails cannot be made.
This routine regulates memory use, rejecting the attempt to make the thumbnails if it cannot find/reserve sufficient memory using MemoryTools.runMemoryIntensiveOperation().
Calls the InputStream version of makeThumbnails().
makeThumbnails in interface HandlermakeThumbnails in class AbstractHandlerunlimitedResources - if true, the generation routine is allowed
to try to use unlimited resources (especially memory)
java.io.IOException
protected byte[] makeThumbnailImage(java.awt.image.BufferedImage imageIn,
boolean std,
int minSize,
int maxSize)
throws java.io.IOException
This uses a binary chop algorithm on the "quality" parameter calling the underlying makeScaledImage() routine to try to get the output file size to reasonable bounds. This may fail to work well, or at all, if the image size is not fixed or monotonically increasing with quality, or fails to produce any output at all some some values of the quality parameter. We treat the failure to generate an image as an indication that the quality parameter needs to be set higher.
The output image will, if possible, use the same colour scheme and other characteristics as the input, though some optional features that usually consume extra space, such as interlacing, may be disabled.
If no output can be generated this returns null, which is the default behaviour.
This should adjust the image "quality" with the detail value (adjusted within the bounds supplied by the handler class) to try to tune the output size. For a lossy encoding format such as JPEG this may be the "quality" factor or compression. For a lossless format the may have to be the number of bits-per-pixel that a colour map is reduced to, for example.
This base-class implementation can be overridden by sophisticated handlers.
This first scales the image using a (fast) nearest-pixel method, which should be good for true-colour and palette images.
imageIn - source image; must not be null and must be suitable
for the target formatstd - if true we are making a standard thumbnail,
else we are making a small thumbnailminSize - minimum (floor) size of thumbnail in bytes;
must be non-negative
(can be zero if not required)maxSize - maximum (ceiling) size of thumbnail in bytes;
must be non-negative and no smaller than minSize
(can me Integer.MAX_VALUE if not required)
java.io.IOException
public byte[] makeSizeConstrainedEncodedImage(int lowerQualityBound,
int initialQualityHint,
int upperQualityBound,
java.awt.image.BufferedImage inputImage,
int targetMin,
int targetMax,
int absMinSize,
int absMaxSize,
int targetBytes)
throws java.io.IOException,
java.lang.IllegalArgumentException
This is not possible for all exhibit types.
makeSizeConstrainedEncodedImage in interface HandlermakeSizeConstrainedEncodedImage in class AbstractHandlerupperQualityBound - maximum value of quality to use; non-negativelowerQualityBound - minimum value of quality to use; non-negative
and no greater than upperQualityBoundinitialQualityHint - initial suggested quality hint; non-negative,
no greater than upperQualityBound, no less than lowerQualityBoundinputImage - the input image to encodetargetMin - target lower bound, should be higher than absMinSizetargetMax - target upper bound, should be lower than absMaxSizeabsMinSize - absolute minimum number of bytesabsMaxSize - absolute maximum number of bytestargetBytes - target number of bytes
java.io.IOException - in case of difficulty generating the image
java.lang.IllegalArgumentException - if the arguments are invalidprotected int estimateWorkingMemoryToCreateThumbnails(java.awt.Dimension xyDim)
This assumes still images amongst other things; for movies or animations this may, depending on the processing method, need to be multiplied by the number of frames, for example.
Fudge factors, such as guessed overheads, are liberally sprinkled in.
This assumes that the JVM and the codecs are reasonably efficient in their use of memory, but this is at best a wild guess.
A sophisticated handler may need to override this.
Should not be called if getThumbnailParams() returns null.
xyDim - pixel dimensions of original image; must be non-null
public java.awt.image.BufferedImage decodeImage(java.io.InputStream is)
throws java.io.IOException
Individual handlers may override this default (JAI) implementation if desired.
This does not close its input stream when done.
Calls to this implementation may be serialised because they can be very memory-intensive.
If the underlying decoder routine throws an (unchecked) exception, we absorb (and log) it and return null, thus making us robust in the face of some underlying handler weaknesses.
decodeImage in interface HandlerdecodeImage in class AbstractHandlerjava.io.IOException
public java.awt.Dimension get2DImageDimensions(java.io.InputStream is)
throws java.io.IOException
This does not close its input stream when done.
Calls to this implementation may be serialised because they may be very memory-intensive.
get2DImageDimensions in interface Handlerget2DImageDimensions in class AbstractHandleris - the exhibit as a binary data stream
java.io.IOException - in case of problems with corrupt data
(or a broken exhibit)
protected org.w3c.dom.Node extractSpecificImageMetaData(javax.imageio.metadata.IIOMetadata imageMetadata,
Name.ExhibitFull exhibitName)
This is passed the metadata for the first available image.
This may be a mix of stream and image/frame metadata.
exhibitName - full exhibit name for diagnostics; never null
protected void _trimMetadata(org.w3c.dom.Node n,
Name.ExhibitFull exhibitName)
exhibitName - non-null full exhibit name for diagnostics
public org.w3c.dom.Node getMetadata(java.io.InputStream is,
Name.ExhibitFull exhibitName)
This tries to fetch any stream data and any metadata from the first available image.
Note that this has to turn off the ImageIO file cache to avoid failing since there seems to be no cache clearing.
By default we trim some of the most bulky and least useful data from the metadata, mainly the palette information for indexed images.
This implementation is serialised as it may be very memory-intensive.
getMetadata in interface HandlergetMetadata in class AbstractHandleris - input stream containing exhibit data; never nullexhibitName - full exhibit name (primarily to help with debugging); never null
protected javax.imageio.ImageWriter _getEncoder()
Any non-null value returned should be dispose()d of when finished with.
public boolean canMakeThumbnails()
canMakeThumbnails in interface HandlercanMakeThumbnails in class AbstractHandlerprotected int _reduceColoursQualityThreshold()
Else this is a positive value n, typically 8 or 24, which sets a quality level at/below which the number of colours in the image is reduced to (capped at) 2^n, and the image representation may be tweaked too (eg converted to a palette/indexed format) as a strong hint to the encoder.
public byte[] makeImageBinary(java.awt.image.BufferedImage imageIn,
int quality)
throws java.io.IOException
We are careful to dispose() of our write when done to release resources.
makeImageBinary in interface HandlermakeImageBinary in class AbstractHandlerimageIn - single image to encode, never nullquality - desired encoding quality in range 0--100 inclusive,
with 0 interpreted as "high compression is important,"
and 100 (or over) interpreted as "high image quality is important.";
this parameter is ignored where it does not make sense for the format
java.io.IOExceptionprivate static void setJAICacheParams()
See: http://java.sun.com/products/java-media/jai/forDevelopers/jaifaq.html#memory1
|
DHD Multimedia Gallery V1.53.0 | ||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||