diff --git a/src/pixie/fileformats/jpg.nim b/src/pixie/fileformats/jpg.nim index 035780d..7d83c5e 100644 --- a/src/pixie/fileformats/jpg.nim +++ b/src/pixie/fileformats/jpg.nim @@ -12,6 +12,7 @@ type Jpg = object width, height: int components: array[3, Component] + quantizationTables: array[4, array[64, uint8]] template failInvalid() = raise newException(PixieError, "Invalid JPG buffer, unable to load") @@ -71,10 +72,59 @@ proc decodeSOF(jpg: var Jpg, data: seq[uint8], pos: var int) = pos += 3 proc decodeDHT(data: seq[uint8], pos: var int) = - skipSegment(data, pos) + # skipSegment(data, pos) + # debugEcho pos + let + segmentLen = readSegmentLen(data, pos) + stop = pos + segmentLen + pos += 2 -proc decodeDQT(data: seq[uint8], pos: var int) = - skipSegment(data, pos) + while stop - pos >= 17: + let info = data[pos] + if (info and 0b11100000) != 0: + failInvalid() + + var counts: array[17, int] + for codeLen in 1 .. 16: + counts[codeLen] = data[pos + codeLen].int + + debugEcho counts + + pos += 17 + + for codeLen in 1 .. 16: + discard + + break + + pos = stop + +proc decodeDQT(jpg: var Jpg, data: seq[uint8], pos: var int) = + let + segmentLen = readSegmentLen(data, pos) + stop = pos + segmentLen + pos += 2 + + while stop - pos >= 65: + let + info = data[pos] + qt = info and 0b00001111 + precision = info and 0b11110000 + + if qt > 3: + failInvalid() + + if precision != 0: + raise newException( + PixieError, "Unsuppored JPG qantization table precision" + ) + + inc pos + + for i in 0 ..< 64: + jpg.quantizationTables[qt][i] = data[pos + i] + + pos += 64 proc decodeSOS(data: seq[uint8], pos: var int) = let segmentLen = readSegmentLen(data, pos) @@ -144,7 +194,7 @@ proc decodeJpg*(data: seq[uint8]): Image = of 0xC4: # Define Huffman Tables decodeDHT(data, pos) of 0xDB: # Define Quantanization Table(s) - decodeDQT(data, pos) + jpg.decodeDQT(data, pos) # of 0xDD: # Define Restart Interval of 0xDA: # Start of Scan decodeSOS(data, pos) diff --git a/src/pixie/fileformats/png.nim b/src/pixie/fileformats/png.nim index f8c38c1..7397cb7 100644 --- a/src/pixie/fileformats/png.nim +++ b/src/pixie/fileformats/png.nim @@ -469,7 +469,7 @@ proc encodePng*( let compressed = try: - compress(filtered, DefaultCompression, dfZlib) + compress(filtered, BestSpeed, dfZlib) except ZippyError: raise newException( PixieError, "Unexpected error compressing PNG image data" diff --git a/tests/benchmark_png.nim b/tests/benchmark_png.nim index 1b9c586..3486766 100644 --- a/tests/benchmark_png.nim +++ b/tests/benchmark_png.nim @@ -1,16 +1,27 @@ -import pixie/fileformats/png, stb_image/read as stbi, fidget/opengl/perf, nimPNG +import pixie/fileformats/png, stb_image/read as stbi, stb_image/write as stbr, + fidget/opengl/perf, nimPNG let data = readFile("tests/data/lenna.png") -timeIt "pixie": +timeIt "pixie decode": for i in 0 ..< 100: discard decodePng(cast[seq[uint8]](data)) -timeIt "nimPNG": +timeIt "pixie encode": + let decoded = decodePng(cast[seq[uint8]](data)) + for i in 0 ..< 1: + discard encodePng(decoded).len + +timeIt "nimPNG decode": for i in 0 ..< 100: discard decodePNG32(data) -timeIt "stb_image": +timeIt "nimPNG encode": + let decoded = decodePNG32(data) + for i in 0 ..< 100: + discard encodePNG32(decoded.data, decoded.width, decoded.height).pixels.len + +timeIt "stb_image decode": for i in 0 ..< 100: var width, height, channels: int discard loadFromMemory( @@ -20,3 +31,15 @@ timeIt "stb_image": channels, stbi.RGBA ) + +timeIt "stb_image encode": + var width, height, channels: int + let decoded = loadFromMemory( + cast[seq[byte]](data), + width, + height, + channels, + stbi.RGBA + ) + for i in 0 ..< 100: + discard writePNG(width, height, channels, decoded).len diff --git a/tests/images/centerRotation.png b/tests/images/centerRotation.png index 52b891b..9942445 100644 Binary files a/tests/images/centerRotation.png and b/tests/images/centerRotation.png differ diff --git a/tests/images/centerRotationWhite.png b/tests/images/centerRotationWhite.png index 1e1144e..31e4c17 100644 Binary files a/tests/images/centerRotationWhite.png and b/tests/images/centerRotationWhite.png differ diff --git a/tests/images/drawBlend.png b/tests/images/drawBlend.png index ef62fc5..43b43aa 100644 Binary files a/tests/images/drawBlend.png and b/tests/images/drawBlend.png differ diff --git a/tests/images/drawBlendSmooth.png b/tests/images/drawBlendSmooth.png index df7a048..4dd286a 100644 Binary files a/tests/images/drawBlendSmooth.png and b/tests/images/drawBlendSmooth.png differ diff --git a/tests/images/drawOverwrite.png b/tests/images/drawOverwrite.png index ef62fc5..43b43aa 100644 Binary files a/tests/images/drawOverwrite.png and b/tests/images/drawOverwrite.png differ diff --git a/tests/images/drawOverwriteRot.png b/tests/images/drawOverwriteRot.png index 35cedb3..007f69e 100644 Binary files a/tests/images/drawOverwriteRot.png and b/tests/images/drawOverwriteRot.png differ diff --git a/tests/images/masters/centerRotation.png b/tests/images/masters/centerRotation.png index 52b891b..9942445 100644 Binary files a/tests/images/masters/centerRotation.png and b/tests/images/masters/centerRotation.png differ diff --git a/tests/images/masters/centerRotationWhite.png b/tests/images/masters/centerRotationWhite.png index 1e1144e..31e4c17 100644 Binary files a/tests/images/masters/centerRotationWhite.png and b/tests/images/masters/centerRotationWhite.png differ diff --git a/tests/images/masters/drawBlend.png b/tests/images/masters/drawBlend.png index ef62fc5..43b43aa 100644 Binary files a/tests/images/masters/drawBlend.png and b/tests/images/masters/drawBlend.png differ diff --git a/tests/images/masters/drawBlendSmooth.png b/tests/images/masters/drawBlendSmooth.png index df7a048..4dd286a 100644 Binary files a/tests/images/masters/drawBlendSmooth.png and b/tests/images/masters/drawBlendSmooth.png differ diff --git a/tests/images/masters/drawOverwrite.png b/tests/images/masters/drawOverwrite.png index ef62fc5..43b43aa 100644 Binary files a/tests/images/masters/drawOverwrite.png and b/tests/images/masters/drawOverwrite.png differ diff --git a/tests/images/masters/drawOverwriteRot.png b/tests/images/masters/drawOverwriteRot.png index 35cedb3..007f69e 100644 Binary files a/tests/images/masters/drawOverwriteRot.png and b/tests/images/masters/drawOverwriteRot.png differ diff --git a/tests/images/masters/transCompose.c.png b/tests/images/masters/transCompose.c.png index 52b891b..9942445 100644 Binary files a/tests/images/masters/transCompose.c.png and b/tests/images/masters/transCompose.c.png differ diff --git a/tests/images/masters/transCompose.png b/tests/images/masters/transCompose.png index 5fd4195..5e8175b 100644 Binary files a/tests/images/masters/transCompose.png and b/tests/images/masters/transCompose.png differ diff --git a/tests/images/transCompose.c.png b/tests/images/transCompose.c.png index 52b891b..9942445 100644 Binary files a/tests/images/transCompose.c.png and b/tests/images/transCompose.c.png differ diff --git a/tests/images/transCompose.png b/tests/images/transCompose.png index 5fd4195..5e8175b 100644 Binary files a/tests/images/transCompose.png and b/tests/images/transCompose.png differ