         [ unknown-color-type ]
     } case ;
 
-M: png-image stream>image
-    drop [
+: load-png ( stream -- loading-png )
+    [
         <loading-png>
         read-png-header
         read-png-chunks
         parse-ihdr-chunk
-        decode-png
     ] with-input-stream ;
+
+M: png-image stream>image
+    drop load-png png>image ;

: png-image-bytes ( loading-png -- byte-array )
    [ inflate-data ] [ png-group-width ] bi group reverse-png-filter ;

: decode-greyscale ( loading-png -- loading-png )
    unimplemented-color-type ;

: decode-truecolor ( loading-png -- loading-png )
    [ <image> ] dip {
        [ png-image-bytes >>bitmap ]
        [ [ width>> ] [ height>> ] bi 2array >>dim ]
        [ drop RGB >>component-order ubyte-components >>component-type ]
    } cleave ;
    
: decode-indexed-color ( loading-png -- loading-png )
    unimplemented-color-type ;

: decode-greyscale-alpha ( loading-png -- loading-png )
    unimplemented-color-type ;

: decode-truecolor-alpha ( loading-png -- loading-png )
    [ <image> ] dip {
        [ png-image-bytes >>bitmap ]
        [ [ width>> ] [ height>> ] bi 2array >>dim ]

: validate-truecolor-alpha ( loading-png -- loading-png )
    { 8 16 } validate-bit-depth ;

: png>image ( loading-png -- image )
    dup color-type>> {
        { greyscale [ validate-greyscale decode-greyscale ] }
        { truecolor [ validate-truecolor decode-truecolor ] }
