blob: ed1e6097efabdb613462be308f299b4d9afa4e0a [file] [edit]
/*
* Copyright (c) 2014-2021 by Wen Yu
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* or any later version.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
*/
package pixy.image.png;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.InflaterInputStream;
import pixy.util.Reader;
/**
* Reader for PNG textual chunks: iTXT, zTXT, and tEXT.
*
* @author Wen Yu, yuwen_66@yahoo.com
* @version 1.0 01/01/2013
*/
public class TextReader implements Reader {
//
private String keyword;
private String text;
private Chunk chunk;
public TextReader() {
; // Default constructor
}
public TextReader(Chunk chunk) {
setInput(chunk);
}
public String getKeyword() {
return this.keyword;
}
public String getText() {
return text;
}
// Read text chunks to a String
public void read() throws IOException {
StringBuilder sb = new StringBuilder(1024);
byte[] data = chunk.getData();
switch (chunk.getChunkType()) {
case ZTXT:
{
int keyword_len = 0;
while(data[keyword_len]!=0) keyword_len++;
this.keyword = new String(data,0,keyword_len,"UTF-8");
InflaterInputStream ii = new InflaterInputStream(new ByteArrayInputStream(data,keyword_len+2, data.length-keyword_len-2));
InputStreamReader ir = new InputStreamReader(ii,"UTF-8");
BufferedReader br = new BufferedReader(ir);
String read = null;
while((read=br.readLine()) != null) {
sb.append(read);
sb.append("\n");
}
br.close();
break;
}
case TEXT:
{
int keyword_len = 0;
while(data[keyword_len]!=0) keyword_len++;
this.keyword = new String(data,0,keyword_len,"UTF-8");
sb.append(new String(data,keyword_len+1,data.length-keyword_len-1,"UTF-8"));
break;
}
case ITXT:
{
// System.setOut(new PrintStream(new File("TextChunk.txt"),"UTF-8"));
/**
* Keyword: 1-79 bytes (character string)
* Null separator: 1 byte
* Compression flag: 1 byte
* Compression method: 1 byte
* Language tag: 0 or more bytes (character string)
* Null separator: 1 byte
* Translated keyword: 0 or more bytes
* Null separator: 1 byte
* Text: 0 or more bytes
*/
int keyword_len = 0;
int trans_keyword_len = 0;
int lang_flg_len = 0;
boolean compr = false;
while(data[keyword_len]!=0) keyword_len++;
sb.append(new String(data,0,keyword_len,"UTF-8"));
if(data[++keyword_len]==1) compr = true;
keyword_len++;//Skip the compression method byte.
while(data[++keyword_len]!=0) lang_flg_len++;
//////////////////////
sb.append("(");
if(lang_flg_len>0)
sb.append(new String(data,keyword_len-lang_flg_len, lang_flg_len, "UTF-8"));
while(data[++keyword_len]!=0) trans_keyword_len++;
if(trans_keyword_len>0) {
sb.append(" ");
sb.append(new String(data,keyword_len-trans_keyword_len, trans_keyword_len, "UTF-8"));
}
sb.append(")");
this.keyword = sb.toString().replaceFirst("\\(\\)", "");
sb.setLength(0); // Reset StringBuilder
/////////////////////// End of key.
if(compr) {//Compressed text
InflaterInputStream ii = new InflaterInputStream(new ByteArrayInputStream(data,keyword_len+1, data.length-keyword_len-1));
InputStreamReader ir = new InputStreamReader(ii,"UTF-8");
BufferedReader br = new BufferedReader(ir);
String read = null;
while((read=br.readLine()) != null) {
sb.append(read);
sb.append("\n");
}
br.close();
} else { //Uncompressed text
sb.append(new String(data,keyword_len+1,data.length-keyword_len-1,"UTF-8"));
sb.append("\n");
}
sb.deleteCharAt(sb.length() - 1);
break;
}
default:
throw new IllegalArgumentException("Not a valid textual chunk.");
}
this.text = sb.toString();
}
public void setInput(Chunk chunk) {
validate(chunk);
this.chunk = chunk;
try {
read();
} catch (IOException e) {
throw new RuntimeException("TextReader: error reading chunk");
}
}
private static void validate(Chunk chunk) {
if(chunk == null) throw new IllegalArgumentException("Input chunk is null");
if (chunk.getChunkType() != ChunkType.TEXT && chunk.getChunkType() != ChunkType.ZTXT &&
chunk.getChunkType() != ChunkType.ITXT) {
throw new IllegalArgumentException("Not a valid textual chunk.");
}
}
}