package ar.com.hjg.pngj.chunks; import ar.com.hjg.pngj.ImageInfo; import ar.com.hjg.pngj.PngReader; import ar.com.hjg.pngj.PngWriter; /** * Chunk copy policy to apply when copyng from a {@link PngReader} to a * {@link PngWriter}. *
* The constants are bit-masks, they can be OR-ed *
* Reference:
* http://www.w3.org/TR/PNG/#14
*/
public class ChunkCopyBehaviour {
/** Don't copy anything */
public static final int COPY_NONE = 0;
/** copy the palette */
public static final int COPY_PALETTE = 1;
/** copy all 'safe to copy' chunks */
public static final int COPY_ALL_SAFE = 1 << 2;
/**
* copy all, including palette
*/
public static final int COPY_ALL = 1 << 3; // includes palette!
/**
* Copy PHYS chunk (physical resolution)
*/
public static final int COPY_PHYS = 1 << 4; // dpi
/**
* Copy al textual chunks.
*/
public static final int COPY_TEXTUAL = 1 << 5; // all textual types
/**
* Copy TRNS chunk
*/
public static final int COPY_TRANSPARENCY = 1 << 6; //
/**
* Copy unknown chunks (unknown by our factory)
*/
public static final int COPY_UNKNOWN = 1 << 7; // all unknown (by the factory!)
/**
* Copy almost all: excepts only HIST (histogram) TIME and TEXTUAL chunks
*/
public static final int COPY_ALMOSTALL = 1 << 8;
private static boolean maskMatch(int v, int mask) {
return (v & mask) != 0;
}
/**
* Creates a predicate equivalent to the copy mask
*
* Given a copy mask (see static fields) and the ImageInfo of the target * PNG, returns a predicate that tells if a * chunk should be copied. *
* This is a handy helper method, you can also create and set your own * predicate */ public static ChunkPredicate createPredicate(final int copyFromMask, final ImageInfo imgInfo) { return new ChunkPredicate() { public boolean match(PngChunk chunk) { if (chunk.crit) { if (chunk.id.equals(ChunkHelper.PLTE)) { if (imgInfo.indexed && maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_PALETTE)) return true; if (!imgInfo.greyscale && maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_ALL)) return true; } } else { // ancillary boolean text = (chunk instanceof PngChunkTextVar); boolean safe = chunk.safe; // notice that these if are not exclusive if (maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_ALL)) return true; if (safe && maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_ALL_SAFE)) return true; if (chunk.id.equals(ChunkHelper.tRNS) && maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_TRANSPARENCY)) return true; if (chunk.id.equals(ChunkHelper.pHYs) && maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_PHYS)) return true; if (text && maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_TEXTUAL)) return true; if (maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_ALMOSTALL) && !(ChunkHelper.isUnknown(chunk) || text || chunk.id.equals(ChunkHelper.hIST) || chunk.id.equals(ChunkHelper.tIME))) return true; if (maskMatch(copyFromMask, ChunkCopyBehaviour.COPY_UNKNOWN) && ChunkHelper.isUnknown(chunk)) return true; } return false; } }; } }