Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.changeDpiBuffer = changeDpiBuffer;
exports.changeDpiBlob = changeDpiBlob;
exports.changeDpiDataUrl = changeDpiDataUrl;

Expand Down Expand Up @@ -51,6 +52,40 @@ var _H = 'H'.charCodeAt(0);
var _Y = 'Y'.charCodeAt(0);
var _S = 's'.charCodeAt(0);

function isBufferPNG(buffer) {
if (buffer.length < 8) return;
return buffer[0] === 137 && buffer[1] === 80 && buffer[2] === 78 && buffer[3] === 71 && buffer[4] === 13 && buffer[5] === 10 && buffer[6] === 26 && buffer[7] === 10;
}

function isBufferJPEG(buffer) {
if (buffer.length < 3) return;
return buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255;
}

function getType(buffer) {
if (isBufferJPEG(buffer)) {
return JPEG;
}
if (isBufferPNG(buffer)) {
return PNG;
}
}

function mergedTypedArrays(a, b) {
var c = new a.constructor(a.length + b.length);
c.set(a);
c.set(b, a.length);
return c;
}

function changeDpiBuffer(buffer, dpi) {
var headerChunk = new Uint8Array(buffer.slice(0, 33));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once the first 33 bytes are converted to array, can we autoDetect the type? the png signature is fixed and the jpeg more or less too. In this way we can find out the type and having the function require an argument the other do not required.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure!

Copy link
Author

@bmathews bmathews Oct 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added getType method that checks the relevant few header bytes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like this is the png start
137 80 78 71 13 10 26 10 <--- decimal values of the first 8 bytes.

var rest = buffer.slice(33);
var type = getType(buffer);
var changedHeader = changeDpiOnArray(headerChunk, dpi, type);
return mergedTypedArrays(changedHeader, rest);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happen when this gets used in a browsers? can we stop the code reaching this point if Buffer is not supported? Can we add as a peer dependency some module that would allow to use this function in the browser too?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this to be browser/node agnostic.


function changeDpiBlob(blob, dpi) {
// 33 bytes are ok for pngs and jpegs
// to contain the information.
Expand Down
34 changes: 34 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,40 @@ const _H = 'H'.charCodeAt(0);
const _Y = 'Y'.charCodeAt(0);
const _S = 's'.charCodeAt(0);

function isBufferPNG(buffer) {
if (buffer.length < 8) return;
return buffer[0] === 137 && buffer[1] === 80 && buffer[2] === 78 && buffer[3] === 71 && buffer[4] === 13 && buffer[5] === 10 && buffer[6] === 26 && buffer[7] === 10;
}

function isBufferJPEG(buffer) {
if (buffer.length < 3) return;
return buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255;
}

function getType(buffer) {
if (isBufferJPEG(buffer)) {
return JPEG;
}
if (isBufferPNG(buffer)) {
return PNG;
}
}

function mergedTypedArrays(a, b) {
var c = new a.constructor(a.length + b.length);
c.set(a);
c.set(b, a.length);
return c;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so basically this avoid us from referencing Buffer, but giving us buffer compatibility ? or will take in buffer and spit back a typed array?

I can imagine a.constructor to be always the Uint8Array, while the b.constructor can be both Buffer and Uint8Array?

I'm asking because i played very little with buffers in node.

Copy link
Collaborator

@asturur asturur Oct 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I m also wondering about ie11 compatibility here. the new x.constructor never works for me in ie11., this i will test.

Copy link
Author

@bmathews bmathews Oct 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're right about a.constructor always being a Uint8Array. My goal is to maintain whatever type they passed in originally. But I'm remembering now that in node, we wouldn't want to do something equivalent to new Buffer() anyways, since that's deprecated. I'll have to think about this more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we could accept the fact that we mutate the original Buffer we could just use .set on the original object for the new head.

Do you know if Buffer.slice returns a copy or a reference to the data? if it returns a copy we can just copy the argument that comes and then set the new head over it, and return it.

Did not try it yet, so i m still throwing ideas out

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It returns a view into the original buffer. Mutating it will mutate the original.

Copy link
Collaborator

@asturur asturur Oct 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well mutation approach would not work with PNG since the header becomes bigger if the phys chunk is not there.

}

export function changeDpiBuffer(buffer, dpi) {
const headerChunk = new Uint8Array(buffer.slice(0, 33));
const rest = buffer.slice(33);
const type = getType(buffer);
const changedHeader = changeDpiOnArray(headerChunk, dpi, type);
return mergedTypedArrays(changedHeader, rest);
}

export function changeDpiBlob(blob, dpi) {
// 33 bytes are ok for pngs and jpegs
// to contain the information.
Expand Down
9 changes: 8 additions & 1 deletion test/test.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import chai, { expect } from 'chai';
import fs from 'fs';
import { changeDpiDataUrl, changeDpiBlob } from '../src/index';
import { changeDpiDataUrl, changeDpiBlob, changeDpiBuffer } from '../src/index';
import btoa from 'btoa';
import atob from 'atob';

Expand Down Expand Up @@ -58,6 +58,13 @@ describe('It can convert dpi', function() {
expect(Buffer.compare(blob,b)).to.not.equal(0);
});
});
it("JPEG conversion buffer", function() {
const jpeg123 = fs.readFileSync(__dirname + '/jpeg123.jpg');
const jpeg456 = fs.readFileSync(__dirname + '/jpeg456.jpg');
const converted = changeDpiBuffer(jpeg123, 456, 'image/jpeg');
expect(Buffer.compare(converted,jpeg456)).to.equal(0);
expect(Buffer.compare(converted,jpeg123)).to.not.equal(0);
})
// it('PNG conversion blob', function() {
// const b = fs.readFileSync(__dirname + '/test415.png');
// const a = fs.readFileSync(__dirname + '/test830.png');
Expand Down