private static PNGConverterState parsePNGChunks()

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;
    }