Skip to content

Commit

Permalink
Revert "fun/png: Adam7 interlacing."
Browse files Browse the repository at this point in the history
Too many bugs that I can't figure out. Two pixels in every 8x8 grid are
transposed, and images whose dimensions aren't multiples of 8 are
broken. These might be related. I can't see either one though, and this
is ultimately an optional feature which is far less important than
filtering or compression.

This reverts commit 27008bb.

Refs #217.
  • Loading branch information
MostAwesomeDude committed Nov 3, 2020
1 parent c09f1b7 commit 7c89269
Showing 1 changed file with 8 additions and 58 deletions.
66 changes: 8 additions & 58 deletions mast/fun/png.mt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "lib/samplers" =~ [=> makeDiscreteSampler]
import "fun/deflate" =~ [=> deflate]
exports (chunkType, CRC32, chunksOf, makePNG, adam7)
exports (chunkType, CRC32, chunksOf, makePNG)

# http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html

Expand Down Expand Up @@ -98,51 +98,6 @@ def iterpixels(width :Int, height :Int) as DeepFrozen:

return rv

def ifilter(f, iterator) as DeepFrozen:
return def filteredIterator.next(ej):
def [w, h] := iterator.next(ej)
return f(w, h)

def ichain(iterators) as DeepFrozen:
var i := 0
return def chainedIterator.next(ej):
while (i < iterators.size()):
# XXX this seems like it could be done in a better way?
return escape la { iterators[i].next(la) } catch _ {
i += 1
continue
}
throw.eject(ej, "out of iterators")

# Adam7: Produce scanlines for seven different images, each containing
# progressively more pixels. The images, indexed 1-7, are used to
# progressively rebuild the original image, with the following layout:
# 1 6 4 6 2 6 4 6
# 7 7 7 7 7 7 7 7
# 5 6 5 6 5 6 5 6
# 7 7 7 7 7 7 7 7
# 3 6 4 6 3 6 4 6
# 7 7 7 7 7 7 7 7
# 5 6 5 6 5 6 5 6
# 7 7 7 7 7 7 7 7

def adam7(w :Int, h :Int) as DeepFrozen:
return ichain([
# Pass 1: width // 8, height // 8
ifilter(fn w, h { [w << 3, h << 3] }, iterpixels(w >> 3, h >> 3)),
# Pass 2: width // 8 + 4, height // 8
ifilter(fn w, h { [w << 3 | 4, h << 3] }, iterpixels(w >> 3, h >> 3)),
# Pass 3: width // 4, height // 8 + 4
ifilter(fn w, h { [w << 2, h << 3 | 4] }, iterpixels(w >> 2, h >> 3)),
# Pass 4: width // 4 + 2, height // 4 + 2
ifilter(fn w, h { [w << 2 | 2, h << 2 | 2] }, iterpixels(w >> 2, h >> 2)),
# Pass 5: width // 2, height // 4 + 2
ifilter(fn w, h { [w << 1, h << 2 | 2] }, iterpixels(w >> 1, h >> 2)),
# Pass 6: width // 2 + 1, height // 2
ifilter(fn w, h { [w << 1 | 1, h << 1] }, iterpixels(w >> 1, h >> 1)),
# Pass 7: width, height // 2 + 1
ifilter(fn w, h { [w, h << 1 | 1] }, iterpixels(w, h >> 1)),
])

object makePNG as DeepFrozen:
"Pack PNG chunk data into single bytestrings."
Expand All @@ -166,9 +121,11 @@ object makePNG as DeepFrozen:
sampling configuration.
"
return def draw(width :Int4, height :Int4):
# Width, height, bit depth, color type, compression, filter, interlace
# Width, height, bit depth, color type, compression, filter,
# interlace
def ihdr := pack4(width) + pack4(height) + _makeBytes.fromInts([
16, 6, 0, 0, 1,
# XXX as soon as possible, implement interlacing
16, 6, 0, 0, 0,
])
def body := [].diverge(0..!256)
def push(chan :Double):
Expand All @@ -181,21 +138,14 @@ object makePNG as DeepFrozen:
def aspectRatio :Double := width / height
def discreteSampler := makeDiscreteSampler(drawable, config, width, height)

# Use Adam7 always.
def pixelIterable := adam7(width, height)
var lastW :Int := 0
def pixelIterable := iterpixels(width, height)

return object drawingIterable:
to next(ej):
def [w, h] := pixelIterable.next(ej)

# w might not be zero to start a scanline, due to
# interlacing. Rather than extra coordination between the
# interlaced pixel iterable and us, we track whether the
# scanline is freshly happening by whether w is monotone.
# The filter type starts the scanline; 0 is no filter.
if (w <= lastW) { body.push(0) }
lastW := w
# Filter type for this scanline: 0 for no filtering.
if (w.isZero()) { body.push(0) }

def color := discreteSampler.pixelAt(w, h)
# Kludge: Color is premultiplied, but PNG stores colors
Expand Down

0 comments on commit 7c89269

Please sign in to comment.