js check if an image truncated/corrupted data

For png files, I decided that I wanted a solution that did more than just check the first and last bytes of the file to see if they were valid. I wanted a solution that actually made use of the embedded crc codes for each chunk inside the png file to check all the data inside the file for corruption.

Luckily I found a mature library that does this: https://github.com/lukeapage/pngjs

Unfortunately it is rather large. Almost 500 kb for the browser version. It is a fully featured png file manipulation library, which makes this understandable. If you have a use case that needs all these features then you might be ok with paying for the size. But it is too heavy for the simple use case of just wanting to validate a png file.

So I cut out the validation code from it and made a simple little 2.5 kb npm package with just the validation code in it: https://www.npmjs.com/package/png-validator


You can decode an image to an array of bytes:

var src = 'here comes your base64 data'
var imageData = Uint8Array.from(atob(src.replace('data:image/jpeg;base64,', '')), c => c.charCodeAt(0))

JPEGs must start with the bytes FF D8 and end with FF D9, so we check if last two elements of the created array buffer is 255 and 217. See live example.

var imageCorrupted = ((imageData[imageData.length - 1] === 217) && (imageData[imageData.length - 2] === 255));

We can use a similar check for PNGs (live example), which end with an IEND chunk containing this sequence of bytes:

// in hex: 00 00 00 00 49 45 4e 44 ae 42 60 82
var sequence = [0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130];

you could check corrupted pixels by canvas like this code

var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.onload = function(){
    ctx.drawImage(img,0,0);
    var height=this.height;
    var width=this.width;
    var hCenter=Math.round(width/2);
    var corruptedRowsCount=0;
    for(var row=height;row>0;row--){
      var c = ctx.getImageData(hCenter, row, 1, 1).data;
      if(c[0]==0 && c[1]==0 && c[2]==0 && c[3]==0)
          corruptedRowsCount++;
      else 
          break;
    }
    console.log(Math.round(corruptedRowsCount*100/height)+" precent of image is corrupted");
};

img.src="data:image/jpeg;base64,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";
<canvas id="canvas">