main
Matthew Butterick 7 years ago
parent aad217a55e
commit 73b6e6df8f

@ -9,18 +9,19 @@ Grab key chunks from PNG. Doesn't require heavy lifting from libpng.
((or/c input-port? bytes?) . -> . hash?)
(define png (make-hasheq))
(parameterize ([current-input-port (if (input-port? ip-or-bytes)
ip-or-bytes
(open-input-bytes ip-or-bytes))])
ip-or-bytes
(open-input-bytes ip-or-bytes))])
(define header (read-bytes 8))
(let loop ()
(cond
[(eof-object? (peek-byte)) png]
[else
(define chunk-size (readUInt32))
(define chunk-size (read-32bit-integer))
(define chunk-name (read-bytes 4))
(case chunk-name
[(#"IHDR") (hash-set*! png 'width (readUInt32)
'height (readUInt32)
[(#"IHDR") (hash-set*! png
'width (read-32bit-integer)
'height (read-32bit-integer)
'bits (read-byte)
'colorType (read-byte)
'compressionMethod (read-byte)
@ -28,28 +29,28 @@ Grab key chunks from PNG. Doesn't require heavy lifting from libpng.
'interlaceMethod (read-byte))]
[(#"PLTE") (hash-set*! png 'palette (read-bytes chunk-size))]
[(#"IDAT") (hash-set*! png 'imgData (read-bytes chunk-size))]
[(#"tRNS") (read-bytes chunk-size)]
[(#"tEXt") (read-bytes chunk-size)]
[(#"IEND") (hash-set! png 'colors
(case (hash-ref png 'colorType)
[(0 3 4) 1]
[(2 6) 3]))
(hash-set! png 'hasAlphaChannel (member (hash-ref png 'colorType) '(4 6)))
(define colors (+ (hash-ref png 'colors) (if (hash-ref png 'hasAlphaChannel) 1 0)))
(hash-set! png 'pixelBitlength (* (hash-ref png 'bits) colors))
(hash-set! png 'colorSpace
(case (hash-ref png 'colors)
[(1) "DeviceGray"]
[(3) "DeviceRGB"]))]
[(#"tRNS") (read-bytes chunk-size)] ; todo implement this section
[(#"tEXt") (read-bytes chunk-size)] ; todo implement this section
[(#"IEND") (define color-value (case (hash-ref png 'colorType)
[(0 3 4) 1]
[(2 6) 3]))
(define alpha-value (member (hash-ref png 'colorType) '(4 6)))
(hash-set*! png
'colors color-value
'hasAlphaChannel alpha-value
'pixelBitlength (* (hash-ref png 'bits) (+ color-value (if alpha-value 1 0)))
'colorSpace (case color-value
[(1) "DeviceGray"]
[(3) "DeviceRGB"]))]
[else (read-bytes chunk-size)])
(read-bytes 4) ; skip crc
(loop)]))))
(define (readUInt32)
(define (read-32bit-integer)
(integer-bytes->integer (read-bytes 4) #t #t))
(module+ test
(require rackunit)
(check-equal?
(read-png (open-input-file "test/assets/test.png"))
(read-png (file->bytes "test/assets/test.png"))))
(read-png (open-input-file "test/assets/test.png"))
(read-png (file->bytes "test/assets/test.png"))))
Loading…
Cancel
Save