aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunk.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-02-23 14:51:06 +0100
committerSven Gothel <[email protected]>2014-02-23 14:51:06 +0100
commit3352601e0860584509adf2b76f993d03893ded4b (patch)
tree974fccc8c0eb2f5ad9d4ffd741dfc35869ed67b5 /src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunk.java
parentf51933f0ebe9ae030c26c066e59a728ce08b8559 (diff)
parentc67de337a8aaf52e36104c3f13e273aa19d21f1f (diff)
Merge branch 'master' into stash_glyphcache
Conflicts: make/scripts/tests.sh src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java src/jogl/classes/com/jogamp/graph/curve/Region.java src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java src/jogl/classes/com/jogamp/graph/font/Font.java src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java src/jogl/classes/jogamp/graph/curve/text/GlyphString.java src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunk.java')
-rw-r--r--src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunk.java250
1 files changed, 191 insertions, 59 deletions
diff --git a/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunk.java b/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunk.java
index 2df9fd1f3..6cd86eb98 100644
--- a/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunk.java
+++ b/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngChunk.java
@@ -6,26 +6,91 @@ import java.util.HashMap;
import java.util.Map;
import jogamp.opengl.util.pngj.ImageInfo;
-import jogamp.opengl.util.pngj.PngjException;
+import jogamp.opengl.util.pngj.PngjExceptionInternal;
-
-// see http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
+/**
+ * Represents a instance of a PNG chunk.
+ * <p>
+ * See <a
+ * href="http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html">http://www
+ * .libpng.org/pub/png/spec/1.2/PNG-Chunks .html</a> </a>
+ * <p>
+ * Concrete classes should extend {@link PngChunkSingle} or
+ * {@link PngChunkMultiple}
+ * <p>
+ * Note that some methods/fields are type-specific (getOrderingConstraint(),
+ * allowsMultiple()),<br>
+ * some are 'almost' type-specific (id,crit,pub,safe; the exception is
+ * PngUKNOWN), <br>
+ * and the rest are instance-specific
+ */
public abstract class PngChunk {
- public final String id; // 4 letters
+ /**
+ * Chunk-id: 4 letters
+ */
+ public final String id;
+ /**
+ * Autocomputed at creation time
+ */
public final boolean crit, pub, safe;
- private int lenori = -1; // merely informational, for read chunks
- private boolean writePriority = false; // for queued chunks
protected final ImageInfo imgInfo;
- private int chunkGroup = -1; // chunk group where it was read or writen
+ /**
+ * Possible ordering constraint for a PngChunk type -only relevant for
+ * ancillary chunks. Theoretically, there could be more general constraints,
+ * but these cover the constraints for standard chunks.
+ */
+ public enum ChunkOrderingConstraint {
+ /**
+ * no ordering constraint
+ */
+ NONE,
+ /**
+ * Must go before PLTE (and hence, also before IDAT)
+ */
+ BEFORE_PLTE_AND_IDAT,
+ /**
+ * Must go after PLTE but before IDAT
+ */
+ AFTER_PLTE_BEFORE_IDAT,
+ /**
+ * Must before IDAT (before or after PLTE)
+ */
+ BEFORE_IDAT,
+ /**
+ * Does not apply
+ */
+ NA;
+
+ public boolean mustGoBeforePLTE() {
+ return this == BEFORE_PLTE_AND_IDAT;
+ }
+
+ public boolean mustGoBeforeIDAT() {
+ return this == BEFORE_IDAT || this == BEFORE_PLTE_AND_IDAT || this == AFTER_PLTE_BEFORE_IDAT;
+ }
+
+ public boolean mustGoAfterPLTE() {
+ return this == AFTER_PLTE_BEFORE_IDAT;
+ }
+ }
+
+ private boolean priority = false; // For writing. Queued chunks with high priority will be written as soon as
+ // possible
+
+ protected int chunkGroup = -1; // chunk group where it was read or writen
+ protected int length = -1; // merely informational, for read chunks
+ protected long offset = 0; // merely informational, for read chunks
/**
- * This static map defines which PngChunk class correspond to which ChunkID The client can add other chunks to this
- * map statically, before reading
+ * This static map defines which PngChunk class correspond to which ChunkID
+ * <p>
+ * The client can add other chunks to this map statically, before reading an
+ * image, calling PngChunk.factoryRegister(id,class)
*/
- public final static Map<String, Class<? extends PngChunk>> factoryMap = new HashMap<String, Class<? extends PngChunk>>();
+ private final static Map<String, Class<? extends PngChunk>> factoryMap = new HashMap<String, Class<? extends PngChunk>>();
static {
factoryMap.put(ChunkHelper.IDAT, PngChunkIDAT.class);
factoryMap.put(ChunkHelper.IHDR, PngChunkIHDR.class);
@@ -45,6 +110,35 @@ public abstract class PngChunk {
factoryMap.put(ChunkHelper.sRGB, PngChunkSRGB.class);
factoryMap.put(ChunkHelper.hIST, PngChunkHIST.class);
factoryMap.put(ChunkHelper.sPLT, PngChunkSPLT.class);
+ // extended
+ factoryMap.put(PngChunkOFFS.ID, PngChunkOFFS.class);
+ factoryMap.put(PngChunkSTER.ID, PngChunkSTER.class);
+ }
+
+ /**
+ * Registers a chunk-id (4 letters) to be associated with a PngChunk class
+ * <p>
+ * This method should be called by user code that wants to add some chunks
+ * (not implmemented in this library) to the factory, so that the PngReader
+ * knows about it.
+ */
+ public static void factoryRegister(String chunkId, Class<? extends PngChunk> chunkClass) {
+ factoryMap.put(chunkId, chunkClass);
+ }
+
+ /**
+ * True if the chunk-id type is known.
+ * <p>
+ * A chunk is known if we recognize its class, according with
+ * <code>factoryMap</code>
+ * <p>
+ * This is not necessarily the same as being "STANDARD", or being
+ * implemented in this library
+ * <p>
+ * Unknown chunks will be parsed as instances of {@link PngChunkUNKNOWN}
+ */
+ public static boolean isKnown(String id) {
+ return factoryMap.containsKey(id);
}
protected PngChunk(String id, ImageInfo imgInfo) {
@@ -55,29 +149,21 @@ public abstract class PngChunk {
this.safe = ChunkHelper.isSafeToCopy(id);
}
- public abstract ChunkRaw createChunk();
-
- public abstract void parseFromChunk(ChunkRaw c);
-
- // override to make deep copy from read data to write
- public abstract void cloneDataFromRead(PngChunk other);
-
- @SuppressWarnings("unchecked")
- public static <T extends PngChunk> T cloneChunk(T chunk, ImageInfo info) {
- PngChunk cn = factoryFromId(chunk.id, info);
- if (cn.getClass() != chunk.getClass())
- throw new PngjException("bad class cloning chunk: " + cn.getClass() + " " + chunk.getClass());
- cn.cloneDataFromRead(chunk);
- return (T) cn;
- }
-
+ /**
+ * This factory creates the corresponding chunk and parses the raw chunk.
+ * This is used when reading.
+ */
public static PngChunk factory(ChunkRaw chunk, ImageInfo info) {
PngChunk c = factoryFromId(ChunkHelper.toString(chunk.idbytes), info);
- c.lenori = chunk.len;
- c.parseFromChunk(chunk);
+ c.length = chunk.len;
+ c.parseFromRaw(chunk);
return c;
}
+ /**
+ * Creates one new blank chunk of the corresponding type, according to
+ * factoryMap (PngChunkUNKNOWN if not known)
+ */
public static PngChunk factoryFromId(String cid, ImageInfo info) {
PngChunk chunk = null;
try {
@@ -87,66 +173,112 @@ public abstract class PngChunk {
chunk = constr.newInstance(info);
}
} catch (Exception e) {
- // this can happend for unkown chunks
+ // this can happen for unkown chunks
}
if (chunk == null)
chunk = new PngChunkUNKNOWN(cid, info);
return chunk;
}
- protected ChunkRaw createEmptyChunk(int len, boolean alloc) {
+ protected final ChunkRaw createEmptyChunk(int len, boolean alloc) {
ChunkRaw c = new ChunkRaw(len, ChunkHelper.toBytes(id), alloc);
return c;
}
- @Override
- public String toString() {
- return "chunk id= " + id + " (" + lenori + ") c=" + getClass().getSimpleName();
+ /**
+ * Makes a clone (deep copy) calling {@link #cloneDataFromRead(PngChunk)}
+ */
+ @SuppressWarnings("unchecked")
+ public static <T extends PngChunk> T cloneChunk(T chunk, ImageInfo info) {
+ PngChunk cn = factoryFromId(chunk.id, info);
+ if (cn.getClass() != chunk.getClass())
+ throw new PngjExceptionInternal("bad class cloning chunk: " + cn.getClass() + " " + chunk.getClass());
+ cn.cloneDataFromRead(chunk);
+ return (T) cn;
}
- void setPriority(boolean highPrioriy) {
- writePriority = highPrioriy;
+ /**
+ * In which "chunkGroup" (see {@link ChunksList}for definition) this chunks
+ * instance was read or written.
+ * <p>
+ * -1 if not read or written (eg, queued)
+ */
+ final public int getChunkGroup() {
+ return chunkGroup;
}
- void write(OutputStream os) {
- ChunkRaw c = createChunk();
- if (c == null)
- throw new PngjException("null chunk ! creation failed for " + this);
- c.writeChunk(os);
+ /**
+ * @see #getChunkGroup()
+ */
+ final public void setChunkGroup(int chunkGroup) {
+ this.chunkGroup = chunkGroup;
}
- public boolean isWritePriority() {
- return writePriority;
+ public boolean hasPriority() {
+ return priority;
}
- /** must be overriden - only relevant for ancillary chunks */
- public boolean allowsMultiple() {
- return false; // override if allows multiple ocurrences
+ public void setPriority(boolean priority) {
+ this.priority = priority;
}
- /** mustGoBeforeXX/After must be overriden - only relevant for ancillary chunks */
- public boolean mustGoBeforeIDAT() {
- return false;
+ final void write(OutputStream os) {
+ ChunkRaw c = createRawChunk();
+ if (c == null)
+ throw new PngjExceptionInternal("null chunk ! creation failed for " + this);
+ c.writeChunk(os);
}
- public boolean mustGoBeforePLTE() {
- return false;
+ public int getLength() {
+ return length;
}
- public boolean mustGoAfterPLTE() {
- return false;
- }
+ /*
+ * public void setLength(int length) { this.length = length; }
+ */
- static boolean isKnown(String id) {
- return factoryMap.containsKey(id);
+ public long getOffset() {
+ return offset;
}
- public int getChunkGroup() {
- return chunkGroup;
+ public void setOffset(long offset) {
+ this.offset = offset;
}
- public void setChunkGroup(int chunkGroup) {
- this.chunkGroup = chunkGroup;
+ /**
+ * Creates the physical chunk. This is used when writing (serialization).
+ * Each particular chunk class implements its own logic.
+ *
+ * @return A newly allocated and filled raw chunk
+ */
+ public abstract ChunkRaw createRawChunk();
+
+ /**
+ * Parses raw chunk and fill inside data. This is used when reading
+ * (deserialization). Each particular chunk class implements its own logic.
+ */
+ public abstract void parseFromRaw(ChunkRaw c);
+
+ /**
+ * Makes a copy of the chunk.
+ * <p>
+ * This is used when copying chunks from a reader to a writer
+ * <p>
+ * It should normally be a deep copy, and after the cloning
+ * this.equals(other) should return true
+ */
+ public abstract void cloneDataFromRead(PngChunk other);
+
+ public abstract boolean allowsMultiple(); // this is implemented in PngChunkMultiple/PngChunSingle
+
+ /**
+ * see {@link ChunkOrderingConstraint}
+ */
+ public abstract ChunkOrderingConstraint getOrderingConstraint();
+
+ @Override
+ public String toString() {
+ return "chunk id= " + id + " (len=" + length + " offset=" + offset + ") c=" + getClass().getSimpleName();
}
}