in pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PNGConverter.java [765:891]
private static PNGConverterState parsePNGChunks(byte[] imageData)
{
if (imageData.length < 20)
{
LOG.error("ByteArray way to small: {}", imageData.length);
return null;
}
PNGConverterState state = new PNGConverterState();
int ptr = 8;
int firstChunkType = readInt(imageData, ptr + 4);
if (firstChunkType != CHUNK_IHDR)
{
LOG.error(String.format("First Chunktype was %08X, not IHDR", firstChunkType));
return null;
}
while (ptr + 12 <= imageData.length)
{
int chunkLength = readInt(imageData, ptr);
int chunkType = readInt(imageData, ptr + 4);
ptr += 8;
if (ptr + chunkLength + 4 > imageData.length)
{
LOG.error(
"Not enough bytes. At offset {} are {} bytes expected. Overall length is {}",
ptr, chunkLength, imageData.length);
return null;
}
Chunk chunk = new Chunk();
chunk.chunkType = chunkType;
chunk.bytes = imageData;
chunk.start = ptr;
chunk.length = chunkLength;
switch (chunkType)
{
case CHUNK_IHDR:
if (state.IHDR != null)
{
LOG.error("Two IHDR chunks? There is something wrong.");
return null;
}
state.IHDR = chunk;
break;
case CHUNK_IDAT:
// The image data itself
state.IDATs.add(chunk);
break;
case CHUNK_PLTE:
// For indexed images the palette table
if (state.PLTE != null)
{
LOG.error("Two PLTE chunks? There is something wrong.");
return null;
}
state.PLTE = chunk;
break;
case CHUNK_IEND:
// We are done, return the state
return state;
case CHUNK_TRNS:
// For indexed images the alpha transparency table
if (state.tRNS != null)
{
LOG.error("Two tRNS chunks? There is something wrong.");
return null;
}
state.tRNS = chunk;
break;
case CHUNK_GAMA:
// Gama
state.gAMA = chunk;
break;
case CHUNK_CHRM:
// Chroma
state.cHRM = chunk;
break;
case CHUNK_ICCP:
// ICC Profile
state.iCCP = chunk;
break;
case CHUNK_SBIT:
LOG.debug("Can't convert PNGs with sBIT chunk.");
break;
case CHUNK_SRGB:
// We use the rendering intent from the chunk
state.sRGB = chunk;
break;
case CHUNK_TEXT:
case CHUNK_ZTXT:
case CHUNK_ITXT:
// We don't care about this text infos / metadata
break;
case CHUNK_KBKG:
// As we can handle transparency we don't need the background color information.
break;
case CHUNK_HIST:
// We don't need the color histogram
break;
case CHUNK_PHYS:
// The PDImageXObject will be placed by the user however he wants,
// so we can not enforce the physical dpi information stored here.
// We just ignore it.
break;
case CHUNK_SPLT:
// This palette stuff seems editor related, we don't need it.
break;
case CHUNK_TIME:
// We don't need the last image change time either
break;
default:
LOG.debug(String.format("Unknown chunk type %08X, skipping.", chunkType));
break;
}
ptr += chunkLength;
// Read the CRC
chunk.crc = readInt(imageData, ptr);
ptr += 4;
}
LOG.error("No IEND chunk found.");
return null;
}