-
-
Save linuxenko/b98c065e87512b85ce03d05eb276e4c2 to your computer and use it in GitHub Desktop.
Encode text into a PNG
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const kCRCTable = new Int32Array([ | |
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, | |
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, | |
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, | |
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, | |
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, | |
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, | |
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, | |
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, | |
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, | |
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, | |
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, | |
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, | |
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, | |
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, | |
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, | |
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, | |
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, | |
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, | |
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, | |
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | |
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, | |
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, | |
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, | |
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, | |
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, | |
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, | |
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, | |
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, | |
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, | |
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, | |
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, | |
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, | |
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, | |
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, | |
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, | |
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, | |
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, | |
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, | |
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, | |
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | |
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, | |
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, | |
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d | |
]); | |
// CRC32 implementation taken from: https://github.com/ashi009/node-fast-crc32c | |
function crc32(buf, i, end, initial) { | |
var crc = initial ^ -1; | |
for (; i < end; ++i) | |
crc = kCRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8); | |
return (crc ^ -1) >>> 0; | |
} | |
const header = Buffer.from([ | |
// PNG header | |
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, | |
// IHDR chunk | |
0x00, 0x00, 0x00, 0x0D, | |
0x49, 0x48, 0x44, 0x52, | |
0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, | |
0x08, 0x06, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00 | |
]); | |
const IEND = Buffer.from([ | |
0x00, 0x00, 0x00, 0x00, | |
0x49, 0x45, 0x4E, 0x44, | |
0xAE, 0x42, 0x60, 0x82 | |
]); | |
const zlib = require('zlib'); | |
const fs = require('fs'); | |
const rgba = []; | |
var len = 0; | |
process.stdin.on('data', (chunk) => { | |
len += chunk.length; | |
rgba[rgba.length] = chunk; | |
}).on('end', () => { | |
const fd = fs.openSync('output_node.png', 'w'); | |
const IMAGE_WIDTH = Math.ceil(Math.sqrt(len)); | |
header.writeUInt32BE(IMAGE_WIDTH, 16, true); | |
header.writeUInt32BE(IMAGE_WIDTH, 20, true); | |
header.writeUInt32BE(crc32(header, 12, 12 + 17, 0), 29, true); | |
fs.writeSync(fd, header, 0, header.length, null); | |
const compress = zlib.createDeflate(); | |
compress.on('data', function(data) { | |
const chunkhdr = Buffer.allocUnsafe(8); | |
chunkhdr.writeUInt32BE(data.length, 0, true); | |
chunkhdr[4] = 0x49; | |
chunkhdr[5] = 0x44; | |
chunkhdr[6] = 0x41; | |
chunkhdr[7] = 0x54; | |
fs.writeSync(fd, chunkhdr, 0, chunkhdr.length, null); | |
fs.writeSync(fd, data, 0, data.length, null); | |
const crc = Buffer.allocUnsafe(4); | |
crc.writeUInt32BE(crc32(data, 0, data.length, 900662814), 0, true); | |
fs.writeSync(fd, crc, 0, crc.length, null); | |
}).on('end', function() { | |
fs.writeSync(fd, IEND, 0, IEND.length, null); | |
fs.closeSync(fd); | |
}); | |
compress.write(Buffer.concat(rgba, len)); | |
if ((len % 4) !== 0) // Write zero bytes for unused bytes/pixels | |
compress.write(Buffer.alloc((IMAGE_WIDTH * IMAGE_WIDTH * 4) - len)); | |
compress.end(); | |
}); | |
process.on('exit', function() { | |
time = process.hrtime(time); | |
console.error('%ds %dms', time[0], time[1] / 1000000); | |
}); | |
var time = process.hrtime(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment