diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngMetadata.java')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngMetadata.java | 198 |
1 files changed, 148 insertions, 50 deletions
diff --git a/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngMetadata.java b/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngMetadata.java index a82754588..52d1b22c1 100644 --- a/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngMetadata.java +++ b/src/jogl/classes/jogamp/opengl/util/pngj/chunks/PngMetadata.java @@ -1,68 +1,70 @@ package jogamp.opengl.util.pngj.chunks; -import jogamp.opengl.util.pngj.PngHelper; +import java.util.ArrayList; +import java.util.List; + +import jogamp.opengl.util.pngj.PngHelperInternal; import jogamp.opengl.util.pngj.PngjException; /** * We consider "image metadata" every info inside the image except for the most basic image info (IHDR chunk - ImageInfo * class) and the pixels values. - * + * <p> * This includes the palette (if present) and all the ancillary chunks - * + * <p> * This class provides a wrapper over the collection of chunks of a image (read or to write) and provides some high * level methods to access them - * */ public class PngMetadata { - private final ChunkList chunkList; + private final ChunksList chunkList; private final boolean readonly; - public PngMetadata(ChunkList chunks, boolean readonly) { + public PngMetadata(ChunksList chunks) { this.chunkList = chunks; - this.readonly = readonly; + if (chunks instanceof ChunksListForWrite) { + this.readonly = false; + } else { + this.readonly = true; + } } /** * Queues the chunk at the writer + * <p> + * lazyOverwrite: if true, checks if there is a queued "equivalent" chunk and if so, overwrites it. However if that + * not check for already written chunks. */ - public boolean setChunk(PngChunk c, boolean overwriteIfPresent) { + public void queueChunk(final PngChunk c, boolean lazyOverwrite) { + ChunksListForWrite cl = getChunkListW(); if (readonly) throw new PngjException("cannot set chunk : readonly metadata"); - return chunkList.setChunk(c, overwriteIfPresent); + if (lazyOverwrite) { + ChunkHelper.trimList(cl.getQueuedChunks(), new ChunkPredicate() { + public boolean match(PngChunk c2) { + return ChunkHelper.equivalent(c, c2); + } + }); + } + cl.queue(c); } - - /** - * Returns only one chunk or null if nothing found - does not include queued chunks - * - * If more than one chunk (after filtering by inner id) is found, then an exception is thrown (failifMultiple=true) - * or the last one is returned (failifMultiple=false) - * - * @param id Chunk id - * @param innerid if not null, the chunk is assumed to be PngChunkTextVar or PngChunkSPLT, and filtered by that 'internal id' - * @param failIfMultiple throw exception if more that one - * @return chunk (not cloned) - */ - public PngChunk getChunk1(String id, String innerid, boolean failIfMultiple) { - return chunkList.getChunk1(id, innerid, failIfMultiple); + public void queueChunk(final PngChunk c) { + queueChunk(c, true); } - /** - * Same as getChunk1(id, innerid=null, failIfMultiple=true); - */ - public PngChunk getChunk1(String id) { - return chunkList.getChunk1(id); + private ChunksListForWrite getChunkListW() { + return (ChunksListForWrite) chunkList; } // ///// high level utility methods follow //////////// // //////////// DPI - /** - * returns -1 if not found or dimension unknown - **/ + /** + * returns -1 if not found or dimension unknown + */ public double[] getDpi() { - PngChunk c = getChunk1(ChunkHelper.pHYs, null, true); + PngChunk c = chunkList.getById1(ChunkHelper.pHYs, true); if (c == null) return new double[] { -1, -1 }; else @@ -76,31 +78,68 @@ public class PngMetadata { public void setDpi(double x, double y) { PngChunkPHYS c = new PngChunkPHYS(chunkList.imageInfo); c.setAsDpi2(x, y); - setChunk(c, true); + queueChunk(c); } // //////////// TIME - public void setTimeNow(int secsAgo) { + /** + * Creates a time chunk with current time, less secsAgo seconds + * <p> + * + * @return Returns the created-queued chunk, just in case you want to examine or modify it + */ + public PngChunkTIME setTimeNow(int secsAgo) { PngChunkTIME c = new PngChunkTIME(chunkList.imageInfo); c.setNow(secsAgo); - setChunk(c, true); + queueChunk(c); + return c; + } + + public PngChunkTIME setTimeNow() { + return setTimeNow(0); } - public void setTimeYMDHMS(int yearx, int monx, int dayx, int hourx, int minx, int secx) { + /** + * Creates a time chunk with diven date-time + * <p> + * + * @return Returns the created-queued chunk, just in case you want to examine or modify it + */ + public PngChunkTIME setTimeYMDHMS(int yearx, int monx, int dayx, int hourx, int minx, int secx) { PngChunkTIME c = new PngChunkTIME(chunkList.imageInfo); c.setYMDHMS(yearx, monx, dayx, hourx, minx, secx); - setChunk(c, true); + queueChunk(c, true); + return c; + } + + /** + * null if not found + */ + public PngChunkTIME getTime() { + return (PngChunkTIME) chunkList.getById1(ChunkHelper.tIME); } public String getTimeAsString() { - PngChunk c = getChunk1(ChunkHelper.tIME, null, true); - return c != null ? ((PngChunkTIME) c).getAsString() : ""; + PngChunkTIME c = getTime(); + return c == null ? "" : c.getAsString(); } // //////////// TEXT - public void setText(String k, String val, boolean useLatin1, boolean compress) { + /** + * Creates a text chunk and queue it. + * <p> + * + * @param k + * : key (latin1) + * @param val + * (arbitrary, should be latin1 if useLatin1) + * @param useLatin1 + * @param compress + * @return Returns the created-queued chunks, just in case you want to examine, touch it + */ + public PngChunkTextVar setText(String k, String val, boolean useLatin1, boolean compress) { if (compress && !useLatin1) throw new PngjException("cannot compress non latin text"); PngChunkTextVar c; @@ -115,21 +154,80 @@ public class PngMetadata { ((PngChunkITXT) c).setLangtag(k); // we use the same orig tag (this is not quite right) } c.setKeyVal(k, val); - setChunk(c, true); + queueChunk(c, true); + return c; } - public void setText(String k, String val) { - setText(k, val, false, val.length() > 400); + public PngChunkTextVar setText(String k, String val) { + return setText(k, val, false, false); } - /** tries all text chunks - returns null if not found */ + /** + * gets all text chunks with a given key + * <p> + * returns null if not found + * <p> + * Warning: this does not check the "lang" key of iTxt + */ + @SuppressWarnings("unchecked") + public List<? extends PngChunkTextVar> getTxtsForKey(String k) { + @SuppressWarnings("rawtypes") + List c = new ArrayList(); + c.addAll(chunkList.getById(ChunkHelper.tEXt, k)); + c.addAll(chunkList.getById(ChunkHelper.zTXt, k)); + c.addAll(chunkList.getById(ChunkHelper.iTXt, k)); + return c; + } + + /** + * Returns empty if not found, concatenated (with newlines) if multiple! - and trimmed + * <p> + * Use getTxtsForKey() if you don't want this behaviour + */ public String getTxtForKey(String k) { - PngChunk c = getChunk1(ChunkHelper.tEXt, k, true); - if (c == null) - c = getChunk1(ChunkHelper.zTXt, k, true); - if (c == null) - c = getChunk1(ChunkHelper.iTXt, k, true); - return c != null ? ((PngChunkTextVar) c).getVal() : null; + List<? extends PngChunkTextVar> li = getTxtsForKey(k); + if (li.isEmpty()) + return ""; + StringBuilder t = new StringBuilder(); + for (PngChunkTextVar c : li) + t.append(c.getVal()).append("\n"); + return t.toString().trim(); + } + + /** + * Returns the palette chunk, if present + * + * @return null if not present + */ + public PngChunkPLTE getPLTE() { + return (PngChunkPLTE) chunkList.getById1(PngChunkPLTE.ID); + } + + /** + * Creates a new empty palette chunk, queues it for write and return it to the caller, who should fill its entries + */ + public PngChunkPLTE createPLTEChunk() { + PngChunkPLTE plte = new PngChunkPLTE(chunkList.imageInfo); + queueChunk(plte); + return plte; + } + + /** + * Returns the TRNS chunk, if present + * + * @return null if not present + */ + public PngChunkTRNS getTRNS() { + return (PngChunkTRNS) chunkList.getById1(PngChunkTRNS.ID); + } + + /** + * Creates a new empty TRNS chunk, queues it for write and return it to the caller, who should fill its entries + */ + public PngChunkTRNS createTRNSChunk() { + PngChunkTRNS trns = new PngChunkTRNS(chunkList.imageInfo); + queueChunk(trns); + return trns; } } |