Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented interlacing support for Node.js (in JavaScript, not CoffeeScript). #8

Open
eddyb opened this issue Oct 21, 2012 · 11 comments

Comments

@eddyb
Copy link

eddyb commented Oct 21, 2012

I wanted to make sure this works, so I didn't try to fiddle with png-node.coffee, I modified the .js output.

    PNG.prototype.decodePixels = function(fn) {
      var _this = this;
      return zlib.inflate(this.imgData, function(err, data) {
        if (err) throw err;
        var pixelBytes = _this.pixelBitlength / 8;
        var fullPixels = new Buffer(_this.width * _this.height * pixelBytes);
        var pos = 0;
        function pass(x0, y0, dx, dy) {
          var byte, c, col, i, left, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft;
          var w = Math.ceil((_this.width - x0) / dx), h = Math.ceil((_this.height - y0) / dy);
          var isFull = _this.width == w && _this.height == h;
          scanlineLength = pixelBytes * w;
          pixels = isFull ? fullPixels : new Buffer(scanlineLength * h);
          row = 0;
          c = 0;
          while (row < h && pos < data.length) {
            switch (data[pos++]) {
              case 0:
                for (i = 0; i < scanlineLength; i += 1) {
                  pixels[c++] = data[pos++];
                }
                break;
              case 1:
                for (i = 0; i < scanlineLength; i += 1) {
                  byte = data[pos++];
                  left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
                  pixels[c++] = (byte + left) % 256;
                }
                break;
              case 2:
                for (i = 0; i < scanlineLength; i += 1) {
                  byte = data[pos++];
                  col = (i - (i % pixelBytes)) / pixelBytes;
                  upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
                  pixels[c++] = (upper + byte) % 256;
                }
                break;
              case 3:
                for (i = 0; i < scanlineLength; i += 1) {
                  byte = data[pos++];
                  col = (i - (i % pixelBytes)) / pixelBytes;
                  left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
                  upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
                  pixels[c++] = (byte + Math.floor((left + upper) / 2)) % 256;
                }
                break;
              case 4:
                for (i = 0; i < scanlineLength; i += 1) {
                  byte = data[pos++];
                  col = (i - (i % pixelBytes)) / pixelBytes;
                  left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
                  if (row === 0) {
                    upper = upperLeft = 0;
                  } else {
                    upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
                    upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + (i % pixelBytes)];
                  }
                  p = left + upper - upperLeft;
                  pa = Math.abs(p - left);
                  pb = Math.abs(p - upper);
                  pc = Math.abs(p - upperLeft);
                  if (pa <= pb && pa <= pc) {
                    paeth = left;
                  } else if (pb <= pc) {
                    paeth = upper;
                  } else {
                    paeth = upperLeft;
                  }
                  pixels[c++] = (byte + paeth) % 256;
                }
                break;
              default:
                throw new Error("Invalid filter algorithm: " + data[pos - 1]);
            }
            if (!isFull) {
              var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes;
              var partPos = row * scanlineLength;
              for (i = 0; i < w; i += 1) {
                for (var j = 0; j < pixelBytes; j += 1)
                  fullPixels[fullPos++] = pixels[partPos++];
                fullPos += (dx - 1) * pixelBytes;
              }
            }
            row++;
          }
        }
        if (_this.interlaceMethod == 1) {
          /*
            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
          */
          pass(0, 0, 8, 8); // 1
          /* NOTE these seem to follow the pattern:
           * pass(x, 0, 2*x, 2*x);
           * pass(0, x,   x, 2*x);
           * with x being 4, 2, 1.
           */
          pass(4, 0, 8, 8); // 2
          pass(0, 4, 4, 8); // 3

          pass(2, 0, 4, 4); // 4
          pass(0, 2, 2, 4); // 5

          pass(1, 0, 2, 2); // 6
          pass(0, 1, 1, 2); // 7
        } else
          pass(0, 0, 1, 1);
        return fn(fullPixels);
      });
    };
ccd0 added a commit to ccd0/transparency-remover that referenced this issue Jun 6, 2015
Update png.js based on
foliojs/png.js#8
with Node dependencies removed.
@mgartner
Copy link

@devongovett any way we can get this support for interlaced PNGs merged in? I need to support interlaced PNGs when using pdfkit. I verified that the above go works well, but I'm not familiar enough with CoffeeScript to easily translate this and create a PR.

@photopea
Copy link

Hi, I wrote my own PNG parser, which supports interlacing: https://github.com/photopea/UPNG.js .

Uzlopak added a commit to parallax/jsPDF that referenced this issue Feb 22, 2018
* Update karma.conf.js

* Merge  (#7)

* Update addimage.js

Solution to solve memory leaks caused by big images.
Is solving the issues #844 and #425

* normalize Color Methods

* f2 => f3

* make it black

* make it gray again

typeof comparison was wrong...

* make typeof comparison wrong to pass test

* Update jspdf.js

d'oh

* Update jspdf.js

correct it again....

* operation fix

ch1 === ch2  === ch3 is wrong. it would process from left to right resulting in a ch1 === ch2 => true, true === ch3 => false

* update test pdf

fix it so that the test is passed

* Update rectangles.pdf

stupid letter

* Update rectangles.pdf

fix length of content

* Update rectangles.pdf

... why?

* Update jspdf.js

DRY it up
add cssColor to rgb  conversion

* Update jspdf.js

bugfix

* Update standard.spec.js

add test for colornames

* Update standard.spec.js

* Update standard.spec.js

* Update jspdf.js

convert short rgb to long form

* Update standard.spec.js

add test case for short rgb-values

* Update jspdf.js

add a setter for the CreationDate

* Update jspdf.js

some major changes to the setCreationDate Algorythm

* Update jspdf.js

bugfix

* Update jspdf.js

darn...

* Update jspdf.js

* Update jspdf.js

* Update jspdf.js

bugfix

* Update addimage.js

round is not the proper method. It has to be ceil so that the splice-method is called atleast once.

* add polyfill for Object.assign

* Add files via upload

* Add files via upload

fix small mistake

* fix tainted standardfontsmetrics

* Add files via upload

one fix

* Update acroform.js

* update references

* modify tests

* force testing

* Update acroform.js

* Add files via upload

* Update acroform.js

* update references

* Add files via upload

* Update acroform.js

* Update acroform.js

* Add files via upload

* Update acroform.js

* Add files via upload

* Add files via upload

* Update acroform.js

* Add files via upload

* addimage.js add cmyk recognition for jpg

* make it less code

* Update saucelabs.karma.conf.js

* Create standard.spec.js

* Create jpg.pdf

* Rename tests/addimage/jpg.pdf to tests/addimage/reference/jpg.pdf

* Add files via upload

* test first if jpeg is working

* Add files via upload

* Update jpeg.spec.js

* Add files via upload

* Add files via upload

* Add files via upload

* Update saucelabs.karma.conf.js

* Update jpg.b64

* Update addhtml.js

#1480

* add ability to recognize filetype by header

* remove unnecessary variable

* typo-fix

* Update addimage.js

* Update addimage.js

#966

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update compare.js

* Update jpeg.spec.js

* Update saucelabs.karma.conf.js

* Update compare.js

* Update compare.js

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update compare.js

* Update jpeg.spec.js

* Add files via upload

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update compare.js

* Update compare.js

D'Oh

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update compare.js

* Update compare.js

* Update jpeg.spec.js

why is here a done? fml

* Add files via upload

* Add files via upload

* Add files via upload

* Delete jpg.b64

* Update jpeg.spec.js

* Update compare.js

* Update saucelabs.karma.conf.js

* Update png.spec.js

* Update saucelabs.karma.conf.js

* Update addimage.js

* Create filetypeRecognition.spec.js

* Update saucelabs.karma.conf.js

* Update filetypeRecognition.spec.js

* Update addimage.js

* fix IE error

* Update standard.spec.js

HideWindowUI.pdf is misssing

* compare.js make it look good

* add tests

* Update saucelabs.karma.conf.js

* Fix for #905 #1163 #1317

adler32cs is no longer maintained, made package.json point to my fork of  adler32cs that contains the loader.js fix

* small modification

* Update outline.js

* Add files via upload

* Update standard.spec.js

* Update karma.conf.js to load outline.js

* Update saucelabs.karma.conf.js to load outline.js

* chore(package): update rollup-plugin-babel to version 3.0.3

* chore(package): update karma to version 2.0.0

* Add new method for internal, getTextColor

* Update dist files and docs to include getTextColor

* Revise getTextColor to return hex code; add new spec

* Compiled assets for getTextColor modifications

* Updates spec and documentation per feedback

* chore(package): update uglify-js to version 3.3.5

Closes #1506

* simplify

* addCreationDate

* Update standard.spec.js

* Update standard.spec.js

* Update jspdf.js

* Update standard.spec.js

* Update standard.spec.js

* Add png adam7 interlace (#6)

* Update png.js

Adapted from here 
foliojs/png.js#8

* make it look good

* fix possible merging error

* fix minor bug

* hopefull removed all dupes

* Update main.js

* Don't skip HideWindowUI

* Update addimage.js

* Update compare.js

* Add files via upload

* Update jspdf.js

* Update jspdf.js

* Update addhtml.js

* Update outline.js

* Update cell.js

* Update annotations.js

* Update from_html.js

* Update context2d.js

* Update acroform.js

* Update addimage.js

* Update karma.conf.js

* Create getImageProperties.spec.js

* typo
Uzlopak added a commit to parallax/jsPDF that referenced this issue May 8, 2018
* Update karma.conf.js

* Merge  (#7)

* Update addimage.js

Solution to solve memory leaks caused by big images.
Is solving the issues #844 and #425

* normalize Color Methods

* f2 => f3

* make it black

* make it gray again

typeof comparison was wrong...

* make typeof comparison wrong to pass test

* Update jspdf.js

d'oh

* Update jspdf.js

correct it again....

* operation fix

ch1 === ch2  === ch3 is wrong. it would process from left to right resulting in a ch1 === ch2 => true, true === ch3 => false

* update test pdf

fix it so that the test is passed

* Update rectangles.pdf

stupid letter

* Update rectangles.pdf

fix length of content

* Update rectangles.pdf

... why?

* Update jspdf.js

DRY it up
add cssColor to rgb  conversion

* Update jspdf.js

bugfix

* Update standard.spec.js

add test for colornames

* Update standard.spec.js

* Update standard.spec.js

* Update jspdf.js

convert short rgb to long form

* Update standard.spec.js

add test case for short rgb-values

* Update jspdf.js

add a setter for the CreationDate

* Update jspdf.js

some major changes to the setCreationDate Algorythm

* Update jspdf.js

bugfix

* Update jspdf.js

darn...

* Update jspdf.js

* Update jspdf.js

* Update jspdf.js

bugfix

* Update addimage.js

round is not the proper method. It has to be ceil so that the splice-method is called atleast once.

* add polyfill for Object.assign

* Add files via upload

* Add files via upload

fix small mistake

* fix tainted standardfontsmetrics

* Add files via upload

one fix

* Update acroform.js

* update references

* modify tests

* force testing

* Update acroform.js

* Add files via upload

* Update acroform.js

* update references

* Add files via upload

* Update acroform.js

* Update acroform.js

* Add files via upload

* Update acroform.js

* Add files via upload

* Add files via upload

* Update acroform.js

* Add files via upload

* addimage.js add cmyk recognition for jpg

* make it less code

* Update saucelabs.karma.conf.js

* Create standard.spec.js

* Create jpg.pdf

* Rename tests/addimage/jpg.pdf to tests/addimage/reference/jpg.pdf

* Add files via upload

* test first if jpeg is working

* Add files via upload

* Update jpeg.spec.js

* Add files via upload

* Add files via upload

* Add files via upload

* Update saucelabs.karma.conf.js

* Update jpg.b64

* Update addhtml.js

#1480

* add ability to recognize filetype by header

* remove unnecessary variable

* typo-fix

* Update addimage.js

* Update addimage.js

#966

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update compare.js

* Update jpeg.spec.js

* Update saucelabs.karma.conf.js

* Update compare.js

* Update compare.js

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update compare.js

* Update jpeg.spec.js

* Add files via upload

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update compare.js

* Update compare.js

D'Oh

* Update compare.js

* Update jpeg.spec.js

* Update compare.js

* Update compare.js

* Update compare.js

* Update jpeg.spec.js

why is here a done? fml

* Add files via upload

* Add files via upload

* Add files via upload

* Delete jpg.b64

* Update jpeg.spec.js

* Update compare.js

* Update saucelabs.karma.conf.js

* Update png.spec.js

* Update saucelabs.karma.conf.js

* Update addimage.js

* Create filetypeRecognition.spec.js

* Update saucelabs.karma.conf.js

* Update filetypeRecognition.spec.js

* Update addimage.js

* fix IE error

* Update standard.spec.js

HideWindowUI.pdf is misssing

* compare.js make it look good

* add tests

* Update saucelabs.karma.conf.js

* Fix for #905 #1163 #1317

adler32cs is no longer maintained, made package.json point to my fork of  adler32cs that contains the loader.js fix

* small modification

* Update outline.js

* Add files via upload

* Update standard.spec.js

* Update karma.conf.js to load outline.js

* Update saucelabs.karma.conf.js to load outline.js

* chore(package): update rollup-plugin-babel to version 3.0.3

* chore(package): update karma to version 2.0.0

* Add new method for internal, getTextColor

* Update dist files and docs to include getTextColor

* Revise getTextColor to return hex code; add new spec

* Compiled assets for getTextColor modifications

* Updates spec and documentation per feedback

* chore(package): update uglify-js to version 3.3.5

Closes #1506

* simplify

* addCreationDate

* Update standard.spec.js

* Update standard.spec.js

* Update jspdf.js

* Update standard.spec.js

* Update standard.spec.js

* Add png adam7 interlace (#6)

* Update png.js

Adapted from here 
foliojs/png.js#8

* make it look good

* fix possible merging error

* fix minor bug

* hopefull removed all dupes

* Update main.js

* Don't skip HideWindowUI

* Update addimage.js

* Update compare.js

* Add files via upload

* Update jspdf.js

* Update jspdf.js

* Update addhtml.js

* Update outline.js

* Update cell.js

* Update annotations.js

* Update from_html.js

* Update context2d.js

* Update acroform.js

* Update addimage.js

* Update karma.conf.js

* Create getImageProperties.spec.js

* typo
@fluke
Copy link

fluke commented Aug 4, 2019

Is it possible to merge this in?

@photopea
Copy link

photopea commented Aug 4, 2019

@kartikluke Why don't you just use UPNG.js instead? It is very small and our custom ZLIB decoder is even faster than pako.js (ZLIB library itself).

@fluke
Copy link

fluke commented Aug 5, 2019

@photopea What is the equivalent in UPNG of:

You can also call PNG.load if you want to load the PNG (but not decode the pixels) synchronously. If you already have the PNG data in a buffer, simply use new PNG(buffer).

@fluke
Copy link

fluke commented Aug 5, 2019

@photopea
Copy link

photopea commented Aug 5, 2019

If you have a file in an ArrayBuffer, just call UPNG.decode(arrayBuffer).

@photopea
Copy link

photopea commented Aug 5, 2019

You can learn how to use UPNG.js at its github page. I would probably not do anything else, if I had to explain how to use UPNG.js to each one of thousands of UPNG users :D

I wonder that people still use libraries, which have not been maintained by the author for seven years, even though there seem to be things that need maintenance (interlacing support).

blikblum added a commit to blikblum/png.js that referenced this issue Sep 26, 2019
blikblum added a commit to blikblum/png.js that referenced this issue Sep 26, 2019
@blikblum
Copy link
Member

The implementation in original post works only for some file types.

See https://github.com/blikblum/pdfkit-interlaced-png example. When replacing the png.js by a patched version only images/interlaced-rgb-alpha-8bit.png is correctly rendered

Any hints on how to fix it is appreciated

@photopea
Copy link

Guys, just switch to UPNG.js, it has more GitHub stars, if that is what you are looking for :D

blikblum added a commit to blikblum/png.js that referenced this issue Sep 29, 2019
@blikblum
Copy link
Member

The implementation in original post works only for some file types.

In fact the implementation is correct. Just need some code in pdfkit side

blikblum added a commit to blikblum/png.js that referenced this issue Nov 16, 2019
leizongmin pushed a commit to leizongmin/png.js that referenced this issue Nov 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants