From a6ea5fe6c2fc05057f5769757eed6aaa5f58a935 Mon Sep 17 00:00:00 2001 From: treeform Date: Sat, 7 May 2022 12:03:03 -0700 Subject: [PATCH] Simplfy component ordering. --- src/pixie/fileformats/jpeg.nim | 50 +++++++----------- .../jpeg/master/cat_4_2_0_progressive.jpg | Bin 0 -> 19027 bytes 2 files changed, 19 insertions(+), 31 deletions(-) create mode 100644 tests/fileformats/jpeg/master/cat_4_2_0_progressive.jpg diff --git a/src/pixie/fileformats/jpeg.nim b/src/pixie/fileformats/jpeg.nim index cdb3020..edca7e2 100644 --- a/src/pixie/fileformats/jpeg.nim +++ b/src/pixie/fileformats/jpeg.nim @@ -344,7 +344,7 @@ proc decodeSOS(state: var DecoderState) = if state.scanComponents notin [1, 3]: failInvalid("unsupported scan component count") - state.componentOrder = @[] + state.componentOrder.setLen(0) for i in 0 ..< state.scanComponents: let @@ -799,40 +799,28 @@ template checkReset(state: var DecoderState) = proc decodeBlocks(state: var DecoderState) = ## Decodes scan data blocks that follow a SOS block. - if state.progressive: - if state.scanComponents == 1: - # Single component pass. - let - comp = state.componentOrder[0] - w = (state.components[comp].width + 7) shr 3 - h = (state.components[comp].height + 7) shr 3 - for column in 0 ..< h: - for row in 0 ..< w: - state.decodeBlock(comp, row, column) - state.checkReset() - else: - # Interleaved component pass. - for y in 0 ..< state.numMcuHigh: - for x in 0 ..< state.numMcuWide: - for comp in state.componentOrder: - for j in 0 ..< state.components[comp].yScale: - for i in 0 ..< state.components[comp].xScale: - let - row = (x * state.components[comp].xScale + i) - column = (y * state.components[comp].yScale + j) - state.decodeBlock(comp, row, column) - state.checkReset() + if state.scanComponents == 1: + # Single component pass. + + let + comp = state.componentOrder[0] + w = (state.components[comp].width + 7) shr 3 + h = (state.components[comp].height + 7) shr 3 + for column in 0 ..< h: + for row in 0 ..< w: + state.decodeBlock(comp, row, column) + state.checkReset() else: # Interleaved regular component pass. - for y in 0 ..< state.numMcuHigh: - for x in 0 ..< state.numMcuWide: + for mcuY in 0 ..< state.numMcuHigh: + for mcuX in 0 ..< state.numMcuWide: for comp in state.componentOrder: - for j in 0 ..< state.components[comp].xScale: - for i in 0 ..< state.components[comp].yScale: + for compY in 0 ..< state.components[comp].xScale: + for compX in 0 ..< state.components[comp].yScale: let - row = (x * state.components[comp].yScale + i) - column = (y * state.components[comp].xScale + j) - state.decodeBlock(comp, row, column) + row = (mcuX * state.components[comp].yScale + compX) + col = (mcuY * state.components[comp].xScale + compY) + state.decodeBlock(comp, row, col) state.checkReset() proc quantizationAndIDCTPass(state: var DecoderState) = diff --git a/tests/fileformats/jpeg/master/cat_4_2_0_progressive.jpg b/tests/fileformats/jpeg/master/cat_4_2_0_progressive.jpg new file mode 100644 index 0000000000000000000000000000000000000000..72ecc4aac94de04aac7d9eddadf2e463b49549ea GIT binary patch literal 19027 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 literal 0 HcmV?d00001