00:00
00:00
mtv129
I'm making a virtual computer on action script 3, ruffle limits me very much

mtv1337 @mtv129

Age 23, Male

as3 and adobe AIR

Ukraine

Joined on 10/22/21

Level:
19
Exp Points:
3,778 / 4,010
Exp Rank:
13,808
Vote Power:
6.08 votes
Rank:
Police Sergeant
Global Rank:
8,523
Blams:
194
Saves:
901
B/P Bonus:
12%
Whistle:
Normal
Trophies:
4
Medals:
861

PNG Chunks parser

Posted by mtv129 - 3 weeks ago


I think that some people need a parser for tea leaves of PNG images, if you go into the technical parts, each PNG file consists of a 16-bit signature and chunks, there are many chunks, then they have the same thing:


1) Data size

2) Chunk name

3) Data

4) CRC

and according to my algorithm for finding chunks, which you see below, you can get all the chunks and their data.


The first chunk will always be IHDR in which the basic data of the PNG file will be drawn, namely: width, height, color depth, color type, compression method (always 0), filtering method (always 0), four-line scan. And the last chunk is IEND which has no data.


In order to get all the chunks you need to check every 4 bytes for the presence of a name, get the data size and using it + CRC key the second chunk with the same parameters will be sent, this is how I did it on haxe

public static function parseChunks(code:String):Array<Dynamic> {
    // Array to store parsed chunks
    var chunks = [];
    
    // Starting index for chunk scanning
    var currentIndex:Int = 16;
    
    // Array of known chunk names and their corresponding hexadecimal representations
    var chunkName:Array<String> = ["IDAT", "IEND", "IHDR", "PLTE", "bKGD", "cHRM", "gAMA", "hIST", "iCCP", "iTXt", "pHYs", "sBIT", "sPLT", "sRGB", "tEXt", "tRNS", "zTXt"];
    var chunkHex:Array<String> = ["49444154", "49454E44", "49484452", "504C5445", "624B4744", "6348524D", "67414D41", "68495354", "69434350", "69545874", "70485973", "73424954", "73504C54", "73524742", "74455874", "74524E53", "7A545874"];
    
    // Loop through the code to find and parse chunks
    while (currentIndex < code.length + 2) {
        // Extract 8 characters from the code as a test chunk
        var testChunk = code.substring(currentIndex, currentIndex + 8);
        
        // Check if the test chunk exists in the list of known chunk hexadecimal representations
        if (chunkHex.indexOf(testChunk) != -1){
            // Calculate the size of data for the current chunk
            var dataSize = Std.parseInt("0x" + code.substring(currentIndex - 8, currentIndex ));
            
            // Get the type of the chunk based on its hexadecimal representation
            var type:String = Bytes.ofHex(testChunk).toString();
            
            // Extract data for the current chunk
            var data = code.substring(currentIndex + 8, currentIndex + 8 + dataSize * 2);
            
            // Extract CRC for the current chunk
            var crc = code.substring(currentIndex + 8 + dataSize * 2, currentIndex + 16 + dataSize * 2);
            
            // Create an object to represent the current chunk and add it to the chunks array
            var object = {
                name: testChunk,
                type: type,
                dataSize: dataSize,
                data: data,
                crc: crc
            };
            chunks.push(object);
            
            // Move the current index to the next chunk
            currentIndex += 16 + dataSize * 2;
        } else {
            // Move the current index by 2 if the test chunk is not found
            currentIndex += 2;
        }
    }
    return chunks;
}

and on Rust

// Function to parse chunks from a PNG file
fn read_chunks(code: String) -> Result<Vec<Chunk>, io::Error> {
    // Array to store parsed chunks
    let mut chunks: Vec<Chunk> = Vec::new();
    
    // Starting index for chunk scanning
    let mut current_index: usize = 16;
    
    // Array of known chunk names and their corresponding hexadecimal representations
    let chunk_hex: Vec<&str> = vec![
        "49444154", "49454E44", "49484452", "504C5445", "624B4744", "6348524D",
        "67414D41", "68495354", "69434350", "69545874", "70485973", "73424954",
        "73504C54", "73524742", "74455874", "74524E53", "7A545874"
    ];
    
    // Loop through the code to find and parse chunks
    while (current_index as usize) < code.len() {
        // Extract 8 characters from the code as a test chunk
        let test_chunk = &code[current_index..current_index + 8];
        
        // Check if the test chunk exists in the list of known chunk hexadecimal representations
        if let Some(_position) = chunk_hex.iter().position(|&s| s == test_chunk.to_string()) {
            // Calculate the size of data for the current chunk
            let hex_string = &code[current_index - 8..current_index];
            let data_size: i128 = i128::from_str_radix(hex_string, 16).unwrap();
            
            // Extract data for the current chunk
            let data = &code[current_index + 8..current_index + 8 + (data_size as usize) * 2];
            
            // Extract CRC for the current chunk
            let crc = &code[current_index + 8 + (data_size as usize) * 2..current_index + 16 + (data_size as usize) * 2];
            
            // Create a chunk object and add it to the chunks vector
            let chunk = Chunk {
                name: test_chunk.to_string(),
                data_size: data_size,
                data: data.to_string(),
                crc: crc.to_string(),
            };
            chunks.push(chunk);
            
            // Move the current index to the next chunk
            current_index += 16 + current_index * 2;
        } else {
            // Move the current index by 2 if the test chunk is not found
            current_index += 2;
        }
    }
    Ok(chunks)
}

Tags:

Comments

Comments ain't a thing here.