PngModule extends ModuleBase { @Override public int parse (InputStream stream, RepInfo info, int parseIndex) throws IOException { initParse (); info.setFormat (_format[0]); info.setMimeType (_mimeType[0]); info.setModule (this); _ckSummer = null; if (_je != null && _je.getChecksumFlag () && info.getChecksum ().size () == 0) { _ckSummer = new Checksummer (); _cstream = new ChecksumInputStream (stream, _ckSummer); _dstream = getBufferedDataStream (_cstream, _je != null ? _je.getBufferSize () : 0); } else { _dstream = getBufferedDataStream (stream, _je != null ? _je.getBufferSize () : 0); } _propList = new LinkedList<> (); _metadata = new Property ("PNGMetadata", PropertyType.PROPERTY, PropertyArity.LIST, _propList); _nisoData = new NisoImageMetadata(); Property nisoProp = new Property(NISO_IMAGE_MD, PropertyType.NISOIMAGEMETADATA, _nisoData); _propList.add(nisoProp); _keywordPropList = new LinkedList<> (); _spltList = new LinkedList<> (); ErrorMessage msg; for (int i = 0; i < _sigBytes.length; i++) { int byt = readUnsignedByte (_dstream); if (byt != _sigBytes[i]) { msg = new ErrorMessage(MessageConstants.PNG_GDM_66); info.setMessage(msg); info.setWellFormed(false); return 0; } } try { for (;;) { PNGChunk chunk = readChunkHead(_dstream); if (chunk == null) { break; } if (iendSeen) { msg = new ErrorMessage (MessageConstants.PNG_GDM_67); info.setMessage (msg); info.setWellFormed (false); return 0; } if (idatSeen && !(chunk instanceof IdatChunk)) { idatFinished = true; } chunk.setModule(this); chunk.setInputStream(_dstream); chunk.setNisoMetadata(_nisoData); chunk.setPropertyList(_propList); chunk.processChunk(info); long storedCRC = chunk.readCRC(); long calculatedCRC = chunk.getCRC(); if (storedCRC != calculatedCRC) { msg = new ErrorMessage(String.format ( MessageConstants.PNG_GDM_68.getMessage() , chunk.chunkTypeString())); info.setMessage(msg); info.setWellFormed(false); return 0; } } } catch (PNGException e) { return 0; } catch (EOFException e) { msg = new ErrorMessage ( String.format ( MessageConstants.PNG_GDM_69.getMessage(), _nByte)); info.setMessage (msg); info.setWellFormed (false); return 0; } catch (Exception e) { msg = new ErrorMessage ( String.format ( MessageConstants.PNG_GDM_70.getMessage() , e.getClass().getName())); info.setMessage (msg); info.setWellFormed (false); return 0; } boolean criticalMissing = false; if (!ihdrSeen) { msg = new ErrorMessage(MessageConstants.PNG_GDM_71); info.setMessage (msg); criticalMissing = true; } if (!idatSeen) { msg = new ErrorMessage(MessageConstants.PNG_GDM_72); info.setMessage (msg); criticalMissing = true; } if (!iendSeen) { msg = new ErrorMessage(MessageConstants.PNG_GDM_73); info.setMessage (msg); criticalMissing = true; } if (criticalMissing) { info.setWellFormed (false); return 0; } if (_colorType == 3 && !plteSeen) { msg = new ErrorMessage (MessageConstants.PNG_GDM_74); info.setMessage (msg); info.setWellFormed (false); return 0; } if ((_colorType == 0 || _colorType == 4) && plteSeen) { msg = new ErrorMessage (MessageConstants.PNG_GDM_75); info.setMessage (msg); info.setWellFormed (false); return 0; } if (!_keywordPropList.isEmpty()) { _propList.add(new Property ("Keywords", PropertyType.PROPERTY, PropertyArity.LIST, _keywordPropList)); } if (!_spltList.isEmpty()) { _propList.add(new Property ("Suggested palettes", PropertyType.PROPERTY, PropertyArity.LIST, _spltList)); } info.setProperty (_metadata); return 0; } PngModule(); @Override void checkSignatures(File file, InputStream stream, RepInfo info); @Override int parse(InputStream stream, RepInfo info, int parseIndex); void eatChunk(PNGChunk chnk); void addKeyword(String keywd, String val); void addKeyword(String keywd, String translatedKeywd, String val, String language); void addSplt(String name, int sampleDepth, int numSamples); void setIhdrSeen(boolean b); boolean isIhdrSeen(); void setIdatSeen(boolean b); void setPlteSeen(boolean b); void setIendSeen(boolean b); boolean isIdatSeen(); boolean isIdatFinished(); boolean isPlteSeen(); void setChunkSeen(int chunkType); boolean isChunkSeen(int chunkType); void setColorType(int ct); int getColorType();  }
@Test public void parsePngWithItxtChunk() throws Exception { final String EXPECTED_ITXTTITLE_VALUE = "PngSuite"; final String EXPECTED_ITXTDISCLAIMER_VALUE = "Freeware."; final String PROP_KEYWORDS = "Keywords"; final String PROP_VALUE = "Value"; File pngFile = new File(ITXTCHUNK_PNG_FILEPATH); RepInfo info = new RepInfo(pngFile.getAbsolutePath()); PngModule pngMod = new PngModule(); pngMod.parse(new FileInputStream(pngFile), info, 0); int wellformed = info.getWellFormed(); int valid = info.getValid(); String type = info.getMimeType(); assertEquals(1, wellformed); assertEquals(1, valid); assertEquals(PNG_MIMETYPE, type); Set<String> keywordValues = new HashSet<String>(); @SuppressWarnings("unchecked") LinkedList<Property> iTxtKeywordProperties = (LinkedList<Property>) info.getByName(PROP_KEYWORDS).getValue(); for (Property prop : iTxtKeywordProperties) { keywordValues.add(prop.getByName(PROP_VALUE).getValue().toString()); } assertEquals(6, keywordValues.size()); assertTrue(keywordValues.contains(EXPECTED_ITXTTITLE_VALUE)); assertTrue(keywordValues.contains(EXPECTED_ITXTDISCLAIMER_VALUE)); }